//
// ViewController.swift
// Audio
//
// Created by MacBookPro on 2017. 11. 28..
// Copyright © 2017년 MacBookPro. All rights reserved.
//
//오디오를 재생하려면 헤더 파일과 델리게이트가 필요하다.
import UIKit
import AVFoundation
class ViewController: UIViewController,AVAudioPlayerDelegate, AVAudioRecorderDelegate{
//변수 및 상수
var audioPlayer : AVAudioPlayer! //avaudioplayer인스턴스 변수
var audioFile : URL! // 재생할 오디오의 파일명 변수
let MAX_VOLUME : Float = 10.0 //최대 불륨, 실수형 상수
var progressTimer : Timer! //타이머를 위한 변수
let timePlayerSelector:Selector = #selector(ViewController.updatePlayTime)
let timeRecordSelector:Selector = #selector(ViewController.updateRecordTime)
//재생 아웃렛 변수
@IBOutlet weak var pvProgressPlay: UIProgressView!
@IBOutlet weak var lbCurrentTime: UILabel!
@IBOutlet weak var lbEndTime: UILabel!
@IBOutlet weak var btnPlay: UIButton!
@IBOutlet weak var btnPause: UIButton!
@IBOutlet weak var btnStop: UIButton!
@IBOutlet weak var slVolume: UISlider!
//녹음 아웃렛 변수
@IBOutlet weak var btnRecord: UIButton!
@IBOutlet weak var lbRecordTime: UILabel!
var audioReorder : AVAudioRecorder!
var isRecorderMode = false //현재는 재생 모드
override func viewDidLoad() {
super.viewDidLoad()
selectAudioFile()
if (!isRecorderMode) {
//오디오를 초기화 하는 함수
initPlay()
//녹음 버튼과 녹음 재생시간은 비활성화
btnRecord.isEnabled = false
lbRecordTime.isEnabled = false
}else{
initRecord()
}
}
//녹음기능 초기화 함수
func selectAudioFile() -> Void {
//재생모드
if !isRecorderMode {
audioFile = Bundle.main.url(forResource: "music", withExtension: "mp3")
}else{//녹음모드
//녹음모드일 때는 새 파일인 recordFile.m4a가 생성 된다.
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
audioFile = documentDirectory.appendingPathComponent("recordFile.m4a")
}
}
//녹음을 위한 초기화 함수 : 음질은 최대, 비트율 320kbps, 오디오 채널은 2, 샘플율은 44,100hz
func initRecord() -> Void {
let recordSettings = [
AVFormatIDKey : NSNumber(value : kAudioFormatAppleLossless as UInt32),
AVEncoderAudioQualityKey : AVAudioQuality.max.rawValue,
AVEncoderBitRateKey : 320000,
AVNumberOfChannelsKey : 2,
AVSampleRateKey : 44100.0] as [String : Any]
do {
// selectAudioFile 함수에서 저장한 audioFile을 url로 하는 audioRecorder 인스턴스를 생성
audioReorder = try AVAudioRecorder(url: audioFile, settings: recordSettings)
} catch let error as NSError {
print("error-initRecord:\(error)")
}
audioReorder.delegate = self
//박자관련
audioReorder.isMeteringEnabled = true
audioReorder.prepareToRecord()
slVolume.value = 1.0
audioPlayer.volume = slVolume.value
lbEndTime.text = convertNSTimeInterval2String(0)
lbCurrentTime.text = convertNSTimeInterval2String(0)
//버튼 모드 비활성화
setPlayButton(false, pause: false, stop: false)
let session = AVAudioSession.sharedInstance()
do {
try session.setCategory(AVAudioSessionCategoryPlayAndRecord)
} catch let error as NSError {
print("error-setcategory : \(error)")
}
do {
try session.setActive(true)
} catch let error as NSError {
print("error-setActive : \(error)")
}
}
//audioFile을 url로 하는 audioplayer 인스턴스 생성
// 입력파라미터인 오디오 파일이 없을 때에 대비하여 try catch문 사용한다.
func initPlay(){
//에러 처리
do {
audioPlayer = try AVAudioPlayer(contentsOf: audioFile) //오류발생 가능 함수
} catch let error as NSError { //오류타입
print("error-initplay : \(error)") //오류타입에 대한 처리 구문
}
//슬라이더의 최대 불륨을 지정
slVolume.maximumValue = MAX_VOLUME
//슬라이더의 불륨을 1.0으로 초기화
slVolume.value = 1.0
//프로그레스 뷰의 진행을 0으로 초기화
pvProgressPlay.progress = 0
//audioplayer의 델리게이트를 self로 한다.
audioPlayer.delegate = self
//prepareToplay 실행한다.
audioPlayer.prepareToPlay()
//오디오 플레이어의 블륨 초기화 한다.
audioPlayer.volume = slVolume.value
//오디오 파일의 재생시간인 audioplayer.duration값을 이 함수를 이용해서 텍스트에 출력
lbEndTime.text = convertNSTimeInterval2String(audioPlayer.duration)
//lbcurrentTime텍스트에는 이 함수를 이용해서 00:00이 출력되도록 한다.
lbCurrentTime.text = convertNSTimeInterval2String(0)
//play 버튼 활성화
//btnPlay.isEnabled = true
//btnPause.isEnabled = false
//btnStop.isEnabled = false
setPlayButton(true, pause: false, stop: false)
}
//
func setPlayButton(_ play:Bool, pause:Bool, stop:Bool) -> Void {
btnPlay.isEnabled = play
btnPause.isEnabled = pause
btnStop.isEnabled = stop
}
//00:00형태로 바꾸기 위해 timeinterval 값을 받아 문자열로 돌려보내는 함수
func convertNSTimeInterval2String(_ time:TimeInterval) -> String {
//재생시간의 매개변수인 time값을 60으로 나눈 몫을 정수 값으로 변환하여 상수 min에 초기화
let min = Int(time/60)
//time값을 60으로 나눈 나머지 값을 정수 값으로 변환하여 상수 sec 값에 초기화 한다.
let sec = Int(time.truncatingRemainder(dividingBy: 60))
//이 두 값을 이용해서 "%02d:%02d" 형태의 문자열로 변환하여 상수에 초기화
let strTime = String(format: "%02d:%02d",min,sec)
return strTime
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//재생 버튼
@IBAction func btnPlayAudio(_ sender: UIButton) {
//오디오 재생
audioPlayer.play()
//재생버튼 비활성화 나머지 버튼 활성화
setPlayButton(false, pause: true, stop: true)
//프로그레스 타이머 설정
progressTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: timePlayerSelector, userInfo: nil, repeats: true)
}
//앞에서 만든 타이머에 의해 0.1초 간격으로 이 함수가 실행되는데, 그때마다 재생시간을 라벨과 프로그래스바에 보여준다.
@objc func updatePlayTime() -> Void {
lbCurrentTime.text = convertNSTimeInterval2String(audioPlayer.currentTime)
pvProgressPlay.progress = Float(audioPlayer.currentTime/audioPlayer.duration)
}
//일시정지버튼
@IBAction func btnPauseAudio(_ sender: UIButton) {
audioPlayer.pause()
setPlayButton(true, pause: false, stop: true)
}
//정지버튼
@IBAction func btnStopAudio(_ sender: UIButton) {
audioPlayer.stop()
//오디오를 정지하고 재생하면 다시 처음부터 재생, 시간 초기화
audioPlayer.currentTime = 0
lbCurrentTime.text = convertNSTimeInterval2String(0)
setPlayButton(true, pause: false, stop: false)
progressTimer.invalidate()
}
//음량 슬라이더 액션 함수
@IBAction func slChangeVolume(_ sender: UISlider) {
audioPlayer.volume = slVolume.value
}
//오디오 재생이 끝나면 맨 처음 상태로 돌아가도록 지정 하는 함수
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
progressTimer.invalidate()
//재생버튼 활성화 나머지 버튼 비활성화
setPlayButton(true, pause: false, stop: false)
}
//녹음 스위치
@IBAction func swRecordMode(_ sender: UISwitch) {
//스위치가 녹음 모드일 때
if sender.isOn {
//오디오 재생 중지, 현재시간 00:00으로 설정, record값 참으로 설정 녹음 버튼과 시간 활성화
audioPlayer.stop()
audioPlayer.currentTime = 0
lbRecordTime!.text = convertNSTimeInterval2String(0)
isRecorderMode = true
btnRecord.isEnabled = true
lbRecordTime.isEnabled = true
}else{
//재생모드일 때, 레코드모드 값을 거짓으로 바꾸고, 녹음 버튼과 시간을 비활성화, 녹음 시간 0
isRecorderMode = false
btnRecord.isEnabled = false
lbRecordTime.isEnabled = false
lbRecordTime.text = convertNSTimeInterval2String(0)
}
//이 함수를 호출해서 오디오 파일을 선택하고 , 모드에 따라서 초기화 할 함수 호출
selectAudioFile()
if !isRecorderMode {
initPlay()
}else {
initRecord()
}
}
//녹음하기 버튼 함수
@IBAction func btnRecord(_ sender: UIButton) {
if sender.titleLabel?.text == "record"{
audioReorder.record()
sender.setTitle("stop", for: UIControlState())
progressTimer=Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: timeRecordSelector, userInfo: nil, repeats: true)
}else {
audioReorder.stop()
progressTimer.invalidate() //녹음이 정지되면 타이머 무효화
sender.setTitle("record", for: UIControlState())
btnPlay.isEnabled = true
initPlay()
}
}
@objc func updateRecordTime(){
lbRecordTime.text = convertNSTimeInterval2String(audioReorder.currentTime)
}
}
'ios 뽀개기 > ios앱' 카테고리의 다른 글
18 ios 스위프트 사진촬영&사진 불러오기 구현 (4) | 2017.11.29 |
---|---|
17 ios 스위프트 동영상 재생 구현 (0) | 2017.11.28 |
15 ios 스위프트 아주 간단한 todo 어플 만들기 (0) | 2017.11.27 |
14 ios 스위프트 네비게이션 바 (0) | 2017.11.27 |
13 ios 스위프트 tapview (0) | 2017.11.23 |
댓글