Playing audio file on iOS in Swift 4
Playing media file in apps is fun. Media usually puts constraints on system resources, but it is ok to indulge in fun once in a while. In this post we will see how to play audio in the iOS app.
Given the high impact of size on the app download, please make sure any sound file you add to project does not exceed the threshold and is well compressed with the reasonable quality
- Adding a sound file in project
First step in producing sound in project is to add sounds file. It could be of any extension such as .mp3
, .wav
etc. You can simply drag and drop the file in your project directory structure. Make sure to check an option which says Copy items if needed
.
To make sure everything is in place after file has been added, select a project, go to Build Phases
tab and under it verify the subgroup which says Copy Bundle Resources
and verify that newly added audio file does exist under it.
If audio file is not present, you can add it by pressing +
button and manually selecting it from the project file system.
AVFoundation
Framework
In order to make audio work in the app, you will have to import AVFoundation
framework. Add following line in the file where you're planning to add code to play the audio
import AVFoundation
- Using
AVAudioPlayer
instance to play the file
In order to play the audio file you will have to initialize the instance of AVAudioPlayer
with URL of audio file in the local file system
Important to note that make sure the instance of
AVAudioPlayer
is not local within the scope. It has to be declared on the top in the file scope. Failure to do so will result in system deallocating created instance right after the scope and no audio will be played.
For example, its declaration will look something like this
class ViewController: UIViewController {
var audioPlayer: AVAudioPlayer?
override func viewDidLoad() {
super.viewDidLoad()
.......
....
..
.
- Playing the audio file
Next, in order to play audio we will need the full path of audio file in the local directory. Swift offers the simple way to achieve it,
Assuming out file name is openmenu.wav
we can use Bundle
API to get full path which takes two parameters, viz. file name and extension and outputs the full URL.
let fileURL = Bundle.main.path(forResource: "openmenu", ofType: "wav")
Note the optional nature of output file path. If file does not exist, you can ignore the further processing with error as follows,
if let fileURL = Bundle.main.path(forResource: "openmenu", ofType: "wav") {
print("Continue processing")
} else {
print("Error: No file with specified name exists")
}
Now that we have full path to audio file in documents directory, we will initialize the AVAudioPlayer
with this parameters
do {
if let fileURL = Bundle.main.path(forResource: "openmenu", ofType: "wav") {
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: fileURL))
} else {
print("No file with specified name exists")
}
} catch let error {
print("Can't play the audio file failed with an error \(error.localizedDescription)")
}
Please note that the initializer block wrapped in the
try-catch
block. TheAVAudioPlayer
initializer throws an error in case it's unable to initialize the instance with specified file parameters
Now we have only one essential thing left to play the audio file. Calling play()
instance method on audioPlayer
object. This method will generate a sound and we're all set
audioPlayer?.play()
Although there is another method -
prepareToPlay
which may be manually called before making a call toplay
, but it's not necessary based on my experience and audio can even be played by directly callingplay
- Controlling number of times to play sound in loop
AVAudioPlayer
allows you to control how many times you want to play audio file in the loop. This is controlled by numberOfLoops
on this instance. By default this value is 0
, meaning audio will be played exactly once without any loop. You can specify any positive non-zero value x
for this parameter in order to play audio exactly x+1
number of times.
For example, if I want to play audio for 2
times, I will specify the following value,
audioPlayer?.numberOfLoops = 1
There is however another option to play it in look continuously. You can set it as -1
audioPlayer?.numberOfLoops = -1
This will make set the audio to play in loop for as long as the app is running.
Hope this helps to anyone who is planning to do awesome things with iOS
AVFoundation
framework. If you have comments, suggestions or concerns, hit me up on Twitter. If you are stuck on any step, please feel free to message me!