• Skip to main content
  • Skip to primary sidebar

Ravi Shankar

Tweaking Apps

  • About
  • Portfolio
  • Privacy Policy

How to record and play sound in Swift

April 12, 2015 By Ravi Shankar 10 Comments

In this tutorial, we are going to see the required steps to record and play sound in Swift Programming language using AVAudioRecorder and AVAudioPlayer

Download source code from github (SoundController.swift)

User Interface

The user interface for this demo is simple with two buttons, one for recording and another for playing sound.

201504121626.jpg

Create corresponding IBAction and IBOutlets from the two button in the View Controller.

@IBOutlet weak var recordButton: UIButton!

@IBOutlet weak var playButton: UIButton!

@IBAction func recordSound(sender: UIButton)

@IBAction func playSound(sender: UIButton)

Dual Purpose Buttons

The Record button will be used to record and stop recording. Similarly the Play button will used to Play and Stop the audio.

Class level var and let declaration

  var soundRecorder: AVAudioRecorder!

var soundPlayer:AVAudioPlayer!

  

let fileName = “demo.caf”

Declare two class level variable for holding an instance of AVAudioRecorder and AvAudioPlayer. Also create constant for holding the file name.

Create Sound file path

For this demo, the sound file will be created under the Cache directory using the name defined in the constant. Add these two function to your class

  func getCacheDirectory() -> String {

  

let paths = NSSearchPathForDirectoriesInDomains(.CachesDirectory,.UserDomainMask, true) as [String]

  

return paths[0]

}

  

func getFileURL() -> NSURL {

  

let path = getCacheDirectory().stringByAppendingPathComponent(fileName)

let filePath = NSURL(fileURLWithPath: path)

  

return filePath!

}

The getCacheDirectory retrieves the caches directory and getFileURL appends the file name with the cache directory.

Setup Recorder

Create a new function that prepares the recorder and this function will be called during the viewDidLoad operation

func setupRecorder() {

  

//set the settings for recorder

  

var recordSettings = [

AVFormatIDKey: kAudioFormatAppleLossless,

AVEncoderAudioQualityKey : AVAudioQuality.Max.rawValue,

AVEncoderBitRateKey : 320000,

AVNumberOfChannelsKey: 2,

AVSampleRateKey : 44100.0

]

  

var error: NSError?

  

soundRecorder = AVAudioRecorder(URL: getFileURL(), settings: recordSettings, error: &error)

  

if let err = error {

println(“AVAudioRecorder error: \(err.localizedDescription)“)

} else {

soundRecorder.delegate = self

soundRecorder.prepareToRecord()

}

}

To create an AVAudioRecorder instance, you need to pass three parameters,

URL– Specifies the path and name of the file where the sound will be recorded.

settings – Configure AVRecorder settings

error – Capture error while creating AVRecorder instance.

If there is no error while creating Audio Recorder, the delegate it set to the View Controller and recorder is prepared for recording. Make sure the View Controller conforms to AVAudioRecorderDelegate

class SoundController: UIViewController, AVAudioRecorderDelegate {

Prepare Player

Add the following function that prepares the AVAudiPlayer to play the recorded sound

func preparePlayer() {

var error: NSError?

  

soundPlayer = AVAudioPlayer(contentsOfURL: getFileURL(), error: &error)

  

if let err = error {

println(“AVAudioPlayer error: \(err.localizedDescription)“)

} else {

soundPlayer.delegate = self

soundPlayer.prepareToPlay()

soundPlayer.volume = 1.0

}

}

AVAudioPlayer instance is created by passing sound file that needs to be played along with pointer to capture errors while creating AVAudioPlayer instance. Make sure the View Controller conforms to AVAudioPlayerDelegate. Then call the prepareToPlay function on the AVAudioPlayer instance.

Implement IBActions function to record and play sound

Add the following implementation to the IBAction functions which records and plays sound.

@IBAction func recordSound(sender: UIButton) {

if (sender.titleLabel?.text == “Record”){

soundRecorder.record()

sender.setTitle(“Stop”, forState: .Normal)

playButton.enabled = false

} else {

soundRecorder.stop()

sender.setTitle(“Record”, forState: .Normal)

}

}

  

@IBAction func playSound(sender: UIButton) {

if (sender.titleLabel?.text == “Play”){

recordButton.enabled = false

sender.setTitle(“Stop”, forState: .Normal)

preparePlayer()

soundPlayer.play()

} else {

soundPlayer.stop()

sender.setTitle(“Play”, forState: .Normal)

}

}

When the Record button is tapped, the name of the button is changed to Stop and starts recording the sound. Similarly when the title is Stop, the recording the stopped and play button is enabled. The same is done when the user taps the play button.

class SoundController: UIViewController, AVAudioRecorderDelegate, AVAudioPlayerDelegate {

Implement AVAudioRecorderDelegate methods

  func audioRecorderDidFinishRecording(recorder: AVAudioRecorder!, successfully flag: Bool) {

playButton.enabled = true

recordButton.setTitle(“Record”, forState: .Normal)

}

  

func audioRecorderEncodeErrorDidOccur(recorder: AVAudioRecorder!, error: NSError!) {

println(“Error while recording audio \(error.localizedDescription)“)

}

Implement AVAudioPlayerDelegate methods

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

recordButton.enabled = true

playButton.setTitle(“Play”, forState: .Normal)

}

  

func audioPlayerDecodeErrorDidOccur(player: AVAudioPlayer!, error: NSError!) {

println(“Error while playing audio \(error.localizedDescription)“)

}

Now you are good to go and try this demo. You can download the source code for recording and playing audio in swift from github.

Filed Under: Develop, Programming, Xcode Tagged With: AvAudioPlayer, AVAudioRecorder, Xcode

Reader Interactions

Comments

  1. Joaquin Aguilar says

    July 27, 2015 at 7:56 pm

    Thank you so much for this tutorial. It’s very helfull to an absolute beginner like me. However, I an looking to program an even simpler app. I need it to have two buttons. One that records and another one that plays back without saving to a file. I want to press record; not pause or save but rather, press the play button and have the app play back the reasent recording. Press record again; have the previous recording purged and so on. Record – play, record – play and so on and on.
    I think this is a stripped down version of your demo app, but, being a total novice, I don’t know what parts of your code need to be stripped or modified. Can you help please?

    Reply
    • Rudy D says

      August 16, 2015 at 9:53 pm

      Hi Joaquin,
      That is exactly what the code does. Record -> saves to cache / Play -> reads from cache.
      Hit Record again -> overwrites cache / Play -> reads from new cache.
      So good news, no stripping needed! Just try it!
      Cheers

      Reply
  2. James says

    September 28, 2015 at 1:52 pm

    Hi love this website! can you convert the program to swift 2 as its throwing up errors i don’t understand

    Reply
    • Ravi Shankar says

      September 29, 2015 at 5:04 pm

      The project has been updated for Swift 2.0, Could you please try now. – https://github.com/rshankras/SwiftDemo

      Reply
  3. Alberto says

    October 14, 2015 at 4:51 pm

    Hey Ravi, thank you for posting up your tutorial, I love how it has the bare bones so I can see exactly what we’re working on. However, I seem to be having some problems with this line of code:
    soundRecorder = AVAudioRecorder(URL: getFileURL(), settings: recordSettings as [NSObject : AnyObject], error: &error)

    “Xcode is telling me that “cannot capture “getfileurl” before it is declared”

    I was wondering if you had any suggestion in order to move forward?

    Thanks!

    Reply
    • Ravi Shankar says

      October 14, 2015 at 5:07 pm

      Thanks. I have made some changes for Swift 2.0 (Xcode 7.0), could you please take the latest from gitHub (https://github.com/rshankras/SwiftDemo). The problematic line is now changed to

      soundRecorder = try AVAudioRecorder(URL: getFileURL(), settings: recordSettings)

      Reply
  4. gabriel says

    October 24, 2015 at 3:56 pm

    Hi rshankar,
    your project only works on simulator, don’t work on devices. I have tested this examples and didn’t work. I think the problem is in the cache path. Do you have a solution ?

    Reply
  5. jyothireddy says

    March 4, 2016 at 5:44 pm

    Thank you ver Much providing this tutorial

    Reply
  6. Karthick says

    November 15, 2016 at 1:06 pm

    Why don’t hear music after recording while headphone is plugged in? What is the solution to record audio in headphone plugged in and out?

    Reply
  7. Suyog Ghinmine says

    July 30, 2019 at 1:50 pm

    The post is really in depth and step by step unlike a lot of other ones I have read so far. I just hope you write a new one for Swift 5. This program doesn’t run anymore on the latest Xcode 10 and Swift 5

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Primary Sidebar

Recent Posts

  • We have blocked all requests from this device – Firebase Phone Authentication
  • iPhone is not available error message in Xcode
  • Clear CocoaPods cache, re-download and reinstall all pods
  • PDFKit – View, Annotate PDF file in Swift
  • Tab Bar Controller with WebView

Archives

  • September 2020
  • April 2020
  • December 2019
  • November 2019
  • October 2019
  • February 2019
  • October 2017
  • June 2017
  • May 2017
  • March 2017
  • September 2016
  • March 2016
  • February 2016
  • January 2016
  • December 2015
  • November 2015
  • October 2015
  • September 2015
  • August 2015
  • July 2015
  • June 2015
  • May 2015
  • April 2015
  • March 2015
  • February 2015
  • January 2015
  • December 2014
  • November 2014
  • October 2014
  • September 2014
  • August 2014
  • July 2014
  • June 2014
  • April 2014
  • March 2014
  • February 2014
  • January 2014
  • December 2013
  • October 2013
  • August 2013
  • July 2013
  • June 2013
  • April 2013
  • March 2013
  • February 2013
  • January 2013
  • November 2012
  • August 2012
  • July 2012
  • June 2012
  • May 2012
  • March 2012
  • February 2012
  • January 2012
  • December 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • April 2011
  • March 2011
  • January 2011
  • September 2010
  • August 2010
  • July 2010
  • June 2010
  • July 2009
  • March 2008

Copyright 2020 © rshankar.com