티스토리 뷰
Xcode(버전11.3)를 AVAudioPlayer 음악(오디오) 재생 및 녹음 앱을 만든다:)
AVAudioPlayer을 이용하여 아래 기능을 구현한다.
1. 오디오 파일을 재생, 일시정지, 정지
2. 볼륨 조절
3. 녹음
- 스토리보드 화면 구성(오디오 재생)
1) Label
'Audio Player', Font - 'System 24.0'
- 스토리보드 화면 구성
2) Progress View
- 스토리보드 화면 구성
3) Label
'currentTime', 'endTime'
- 스토리보드 화면 구성
4) Button
'Play', 'Pause', 'Stop'
- 스토리보드 화면 구성
5) Label
'Volume'
- 스토리보드 화면 구성
6) Slider
- 스토리보드 화면 구성(오디오 녹음)
7) Label
'Record', Font : 'System 20.0'
- 스토리보드 화면 구성
8) Switch
State 'Off'
- 스토리보드 화면 구성
9) Button
'Record'
- 스토리보드 화면 구성
10) Label
'00:00', Label 크기 조절
스토리보드 화면 구성(오디오 재생 및 녹음)이 완성된 모습
- 아웃렛 변수 추가(오디오 재생)
1) Progress View -> 'pvProgressPlay'
2) 'currentTime' Label -> 'lblCurrentTime'
3) 'endTime' Label -> 'lblEndTime'
4) 'Play' Button -> 'btnPlay'
5) 'Pause' Button -> 'btnPause'
6) 'Stop' Button -> 'btnStop'
7) Slider -> 'slVolume'
- 액션 함수 추가(오디오 재생)
1) 'Play' Button -> 'btnPlayAudio'
2) 'Pause' Button -> 'btnPauseAudio'
3) 'Stop' Button -> 'btnStopAudio'
4) Slider -> 'slChangeVolume'
- 아웃렛 변수 추가(오디오 녹음)
1) 'Record' Button -> 'btnRecord'
2) '00:00' Label -> 'lblRecordTime'
- 액션 함수 추가(오디오 녹음)
1) Switch -> 'swRecordMode'
2) 'Record' Button -> 'btnRecord'
- 오디오 파일 추가
재생할 음악을 프로젝트에 추가한다.
전체 소스 보기
//
// ViewController.swift
// day191223_Audio
//
// Created by 무니 on 2019/12/23.
// Copyright © 2019 com.mooni. All rights reserved.
//
import UIKit
import AVFoundation
class ViewController: UIViewController, AVAudioPlayerDelegate, AVAudioRecorderDelegate {
var audioPlayer : AVAudioPlayer! // audioPlayer : 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 var pvProgressPlay: UIProgressView!
@IBOutlet var lblCurrentTime: UILabel!
@IBOutlet var lblEndTime: UILabel!
@IBOutlet var btnPlay: UIButton!
@IBOutlet var btnPause: UIButton!
@IBOutlet var btnStop: UIButton!
@IBOutlet var slVolume: UISlider!
@IBOutlet var btnRecord: UIButton!
@IBOutlet var lblRecordTime: UILabel!
var audioRecoder : AVAudioRecorder!
var isRecordMode = false // '녹음 모드'를 나타내는 변수. 기본값은 false('재생 모드')
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
selectAudioFile()
if !isRecordMode { // 재생 모드일 때(녹음 모드가 아니라면)
initplay()
btnRecord.isEnabled = false
lblRecordTime.isEnabled = false
} else { // 녹음 모드일 때
initRecord()
}
}
// 재생 모드와 녹음 모드에 따라 다른 파일을 선택함
func selectAudioFile(){
if !isRecordMode { // 재생 모드일 때
audioFile = Bundle.main.url(forResource: "Touch", withExtension: "mp3")
} else { // 녹음 모드일 때
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
audioFile = documentDirectory.appendingPathComponent("recordFile.m4a")
}
}
// 녹음 모드의 초기화
func initRecord(){
let recordSettings = [AVFormatIDKey : NSNumber(value: kAudioFormatAppleLossless as UInt32),
AVEncoderAudioQualityKey : AVAudioQuality.max.rawValue,
AVEncoderBitRateKey : 320000,
AVNumberOfChannelsKey : 2,
AVSampleRateKey : 44100.0 ] as [String : Any]
do {
audioRecoder = try AVAudioRecorder(url: audioFile, settings: recordSettings)
} catch let error as NSError {
print("Error-initRecord : \(error)")
}
audioRecoder.delegate = self
audioRecoder.isMeteringEnabled = true
audioRecoder.prepareToRecord()
slVolume.value = 1.0
audioPlayer.volume = slVolume.value
lblEndTime.text = convertNSTimeInterval12String(0)
lblCurrentTime.text = convertNSTimeInterval12String(0)
setPlayButtons(false, pause: false, stop: false)
let session = AVAudioSession.sharedInstance()
do {
try session.setCategory(AVAudioSession.Category.playAndRecord)
} catch let error as NSError {
print(" Error-setCategory : \(error)")
}
do {
try session.setActive(true)
} catch let error as NSError {
print(" Error-setActive : \(error)")
}
}
// 재생 모드의 초기화
func initplay(){
do {
audioPlayer = try AVAudioPlayer(contentsOf: audioFile)
} catch let error as NSError {
print("Error-initPlay : \(error)")
}
slVolume.maximumValue = MAX_VOLUME // 슬라이더(slVolume) 최대 볼륨 10.0으로 초기화
slVolume.value = 1.0 // 슬라이더(slVolume) 볼륨 1.0으로 초기화
pvProgressPlay.progress = 0 // 프로그레스 뷰(pvProgressPlay)의 진행 0으로 초기화
audioPlayer.delegate = self // audioPlayer의 델리게이트는 self
audioPlayer.prepareToPlay() // prepareToPlay() 실행
audioPlayer.volume = slVolume.value // audioaplayer 볼륨을 슬라이더(slVolume) 값 1.0으로 초기화
lblEndTime.text = convertNSTimeInterval12String(audioPlayer.duration)
lblCurrentTime.text = convertNSTimeInterval12String(0)
setPlayButtons(true, pause: false, stop: false)
}
// '재생', '일시 정지', '정지' 버튼을 활성화 또는 비활성화하는 함수
func setPlayButtons(_ play: Bool, pause: Bool, stop: Bool){
btnPlay.isEnabled = play
btnPause.isEnabled = pause
btnStop.isEnabled = stop
}
// 00:00 형태의 문자열로 변환함
func convertNSTimeInterval12String(_ time:TimeInterval) -> String {
let min = Int(time/60)
let sec = Int(time.truncatingRemainder(dividingBy: 60))
let strTime = String(format: "%02d:%02d", min, sec)
return strTime
}
// '재생' 버튼을 클릭하였을 때
@IBAction func btnPlayAudio(_ sender: UIButton) {
audioPlayer.play()
setPlayButtons(false, pause: true, stop: true)
progressTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: timePlayerSelector, userInfo: nil, repeats: true)
}
// 0.1초마다 호출되며 재생 시간을 표시함
@objc func updatePlayTime(){
lblCurrentTime.text = convertNSTimeInterval12String(audioPlayer.currentTime) // 재생 시간인 audioPlayer.currentTime을 lblCurrentTime에 나타냄
pvProgressPlay.progress = Float(audioPlayer.currentTime/audioPlayer.duration) // 프로그레스(Progress View)인 pvProgressPlay의 진행 상황에 audioPlayer.currentTime을 audioPlayer.duration으로 나눈 값으로 표시
}
// '일시 정지' 버튼을 클릭하였을 때
@IBAction func btnPauseAudio(_ sender: UIButton) {
audioPlayer.pause()
setPlayButtons(true, pause: false, stop: true)
}
// '정지' 버튼을 클릭하였을 때
@IBAction func btnStopAudio(_ sender: UIButton) {
audioPlayer.stop()
audioPlayer.currentTime = 0
lblCurrentTime.text = convertNSTimeInterval12String(0)
setPlayButtons(true, pause: false, stop: false)
progressTimer.invalidate() // 타이머 무효화
}
// 볼륨 슬라이더 값을 audioplayer.volume에 대임함
@IBAction func slChangeVolume(_ sender: UISlider) {
audioPlayer.volume = slVolume.value
}
// 재생이 종료되었을 때 호출함
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
progressTimer.invalidate() // 타이머 무효화
setPlayButtons(true, pause: false, stop: false)
}
// 스위치를 ON/Off하여 녹음모드 인지 재생 모드인지를 결정함
@IBAction func swRecordMode(_ sender: UISwitch) {
if sender.isOn { // 녹음 모드일 때
audioPlayer.stop()
audioPlayer.currentTime = 0
lblRecordTime!.text = convertNSTimeInterval12String(0)
isRecordMode = true
btnRecord.isEnabled = true
lblRecordTime.isEnabled = true
} else { // 재생 모드일 때
isRecordMode = false
btnRecord.isEnabled = false
lblRecordTime.isEnabled = false
lblRecordTime.text = convertNSTimeInterval12String(0)
}
selectAudioFile() // 모드에 따라 오디오 파일을 선택함
// 모드에 따라 재생 초기화 또는 녹음 초기화를 수행함
if !isRecordMode { // 녹음 모드가 아닐 때, 즉 재생 모드일 때
initplay()
} else { // 녹음 모드일 때
initRecord()
}
}
@IBAction func btnRecord(_ sender: UIButton) {
if sender.titleLabel?.text == "Record" { // 버튼이 'Record'일 때 녹음을 중지함
audioRecoder.record()
sender.setTitle("Stop", for: UIControl.State())
progressTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: timeRecordSelector, userInfo: nil, repeats: true)
} else { // 버튼이 'Stop'일 때 녹음을 위한 초기화를 수행함
audioRecoder.stop()
progressTimer.invalidate() // 녹음이 중지되면 무효화
sender.setTitle("Record", for: UIControl.State())
btnPlay.isEnabled = true
initplay()
}
}
// 0.1초마다 호출되며 녹음 시간을 표시함
@objc func updateRecordTime(){
lblRecordTime.text = convertNSTimeInterval12String(audioRecoder.currentTime)
}
}
시뮬레이터 결과 화면
'IT > swift' 카테고리의 다른 글
[iOS/swift] AVPlayerViewController 비디오(동영상) 재생 앱 만들기 (0) | 2019.12.26 |
---|---|
[iOS/swift] AVAudioPlayer 음악(오디오) 재생 및 녹음 앱 v2, 이미지를 보여주는 기능 추가하기 (0) | 2019.12.26 |
[iOS/swift] 테이블 뷰 컨트롤러(Table View Controller) 할일 목록 앱v2, 아이콘 선택 기능 추가하기 (0) | 2019.12.23 |
[iOS/swift] 테이블 뷰 컨트롤러(Table View Controller)할일 목록 앱 만들기 (0) | 2019.12.18 |
[iOS/swift] 내비게이션 컨트롤러 (Navigation Controller) 앱 v2, 이미지 확대 축소 기능 추가하기 (0) | 2019.12.17 |