您的位置:首页 > 移动开发 > IOS开发

iOS Programming 101: Record and Play Audio using AVFoundation Framework

2015-12-19 13:57 661 查看
Editor’s note: Some of you asked us to write a tutorial about audio recording. This week, we work with Yiqi Shi and Raymond from Purple Development to
give you an introduction of AVFoundation framework. Yiqi and Raymond are independent iOS developers and have recently released Voice
Memo Wifi that allows users to record voice memo and share it over WiFi.

iOS provides various framework to let you work with sound in your app. One of the frameworks that you can use to play and record audio file is the AV Foundation Framework. In this tutorial, I’ll walk you through the basics of the framework and show you how
to manage audio playback, as well as, recording.

To provide you with a working example, I’ll build a simple audio app that allows users to record and play audio. Our primary focus is to demonstrate the AV Foundation framework so the user interface of the app is very simple.

The AV Foundation provides easy ways to deal with audio. In this tutorial, we mainly deal with these two classes:

AVAudioPlayer – think of it as an audio player for playing sound files. By using the player, you can play sounds of any duration and in any audio format available in iOS.

AVAudioRecorder – an audio recorder for recording audio


Starting with the Project Template

First of all, create a “Single View Application” and name it as “AudioDemo”. To free you from setting up the user interface and code skeleton, you can download
the project template from here.

I’ve created a simple UI for you that it only contains three buttons including “Record”, “Stop” and “Play”. The buttons are also linked up with the code.



AudioDemo Project Template


Adding AVFoundation Framework

By default, the AVFoundation framework is not bundled in any Xcode project. So you have to add it manually. In the Project Navigator, select the “AudioDemo” project. In the Content Area, select “AudioDemo” under Targets and click “Build Phases”. Expand “Link
Binary with Libraries” and click the “+” button to add the “AVFoundation.framework”.



Adding AVFoundation Framework

To use the AVAudioPlayer and AVAudioRecorder class, we need to import in ViewController.h.

1

#import <AVFoundation/AVFoundation.h>


Audio Recording using AVAudioRecorder

First, let’s take a look how we can use AVAudioRecorder to record audio. Add the AVAudioRecorderDelegate protocol and AVAudioPlayerDelegate in the ViewController.h. We’ll explain both delegates as we walk through the code.

1

@interface ViewController : UIViewController <AVAudioRecorderDelegate, AVAudioPlayerDelegate>
Next, declare the instance variables for AVAudioRecorder and AVAudioPlayer in ViewController.m:

1

2

3

4

@interface ViewController () {

AVAudioRecorder *recorder;

AVAudioPlayer *player;

}
The AVAudioRecorder class provides an easy way to record sound in iOS. To use the recorder, you have to prepare a few things:

Specify a sound file URL.

Set up the audio session.

Configure the audio recorder’s initial state.

We’ll do the setup in the “viewDidLoad” method of ViewController.m. Simply edit the method with the following code:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

- (void)viewDidLoad

{

[super viewDidLoad];

// Disable Stop/Play button when application launches

[stopButton setEnabled:NO];

[playButton setEnabled:NO];

// Set the audio file

NSArray *pathComponents = [NSArray arrayWithObjects:

[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],

@"MyAudioMemo.m4a",

nil];

NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];

// Setup audio session

AVAudioSession *session = [AVAudioSession sharedInstance];

[session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

// Define the recorder setting

NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];

[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];

[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];

[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];

// Initiate and prepare the recorder

recorder = [[AVAudioRecorder alloc] initWithURL:outputFileURL
settings:recordSetting error:NULL];

recorder.delegate = self;

recorder.meteringEnabled = YES;

[recorder prepareToRecord];

}
Note: For demo purpose, we skip the error handling. In real app, don’t forget to include proper error handling.

In the above code, we first define the sound file URL for saving the recording. and then configure the audio session. iOS handles audio behaviour of an app by using audio sessions. Upon launch, your app automatically gets an audio session. You can grab such
session by calling [AVAudioSession sharedInstance] and configure it. Here, we tell iOS that the app uses “AVAudioSessionCategoryPlayAndRecord” category which enables both audio input and output. We will not go into the details of audio session but you can
check out the official
document for further details.

The AVAudioRecorder uses a dictionary-based settings for its configuration. In line 21-25, we use the options keys to configure the audio data format, sample rate and number of channels. Lastly, we initiate the audio recorder by calling “prepareToRecord:” method.

Note: For other settings keys, you can refer to AV
Foundation Audio Settings Constants.


Implementing Record Button

We’ve completed the audio preparation. Let’s move on to implement the action method of Record button. Before we dive into the code, let me explain how the “Record” button works. When user taps the “Record” button, the app will start recording and the button
text will be changed to “Pause”. If user taps the “Pause” button, the app will pause the audio recording till the “Record” is tapped again. The audio recording will only be stopped when user taps the “Stop” button.

Edit the “recordPauseTapped:” method with the following code:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

- (IBAction)recordPauseTapped:(id)sender {

// Stop the audio player before recording

if (player.playing) {

[player stop];

}

if (!recorder.recording) {

AVAudioSession *session = [AVAudioSession sharedInstance];

[session setActive:YES error:nil];

// Start recording

[recorder record];

[recordPauseButton setTitle:@"Pause" forState:UIControlStateNormal];

} else {

// Pause recording

[recorder pause];

[recordPauseButton setTitle:@"Record" forState:UIControlStateNormal];

}

[stopButton setEnabled:YES];

[playButton setEnabled:NO];

}
In the above code, we first check whether the audio player is playing. If audio player is playing, we simply stop it by using the “stop:” method. Line 7 of the above code determines if the app is in recording mode. If it’s not in recording mode, the app activates
the audio sessions and starts the recording. For recording to work (or sound to play), your audio session must be active.

In general, you can use the following methods of AVAudioRecorder class to control the recording:

record – start/resume a recording

pause – pause a recording

stop – stop a recording


Implementing Stop Button

For the Stop button, we simply call up the “stop:” method to the recorder, followed by deactivating the audio session. Edit the “stopTapped:” method with the following code:

1

2

3

4

5

6

- (IBAction)stopTapped:(id)sender {

[recorder stop];

AVAudioSession *audioSession = [AVAudioSession sharedInstance];

[audioSession setActive:NO error:nil];

}


Implementing the AVAudioRecorderDelegate Protocol

You can make use of AVAudioRecorderDelegate protocol to handle audio interruptions (say, a phone call during audio recording) and the completion of recording. In the example, the ViewController is the delegate. The methods defined in AVAudioRecorderDelegate
protocol are optional. Here, we’ll only implement the “audioRecorderDidFinishRecording:” method to handle the completion of recording. Add the following code to ViewController.m:

1

2

3

4

5

6

- (void) audioRecorderDidFinishRecording:(AVAudioRecorder *)avrecorder
successfully:(BOOL)flag{

[recordPauseButton setTitle:@"Record" forState:UIControlStateNormal];

[stopButton setEnabled:NO];

[playButton setEnabled:YES];

}
After finishing the recording, we simply change the “Pause” button back to “Record” button.


Playing Sound using AVAudioPlayer

Finally, it comes to the implementation of the “Play” button for audio playback using AVAudioPlayer. In the ViewController.m, edit the “playTapped:” method using the following code:

1

2

3

4

5

6

7

- (IBAction)playTapped:(id)sender {

if (!recorder.recording){

player = [[AVAudioPlayer alloc] initWithContentsOfURL:recorder.url
error:nil];

[player setDelegate:self];

[player play];

}

}
The above code is very straightforward. Normally, there are a few things to configure an audio player:

Initialize the audio play and Assign a sound file to it. In the case, it’s the audio file of the recording (i.e. recorder.url).

Designate an audio player delegate object, which handles interruptions as well as the playback-completed event.

Call play: method to play the sound file.


Implementing the AVAudioPlayerDelegate Protocol

The delegate of an AVAudioPlayer object must adopt the AVAudioPlayerDelegate protocol. In this case, it’s the ViewController. The delegate allows you to handle interruptions, audio decoding errors and update the user interface when an audio has finished playing.
All methods in AVAudioplayerDelegate protocol are optional, however. To demonstrate how it works, we’ll implement the “audioPlayerDidFinishPlaying:” method to display an alert prompt after the completion of audio playback. For usage of other methods, you can
refer to the official
documentation of AUAudioPlayerDelegate protocol.

Add the following code in ViewController.m:

1

2

3

4

5

6

7

8

- (void) audioPlayerDidFinishPlaying:(AVAudioPlayer *)player
successfully:(BOOL)flag{

UIAlertView *alert = [[UIAlertView
alloc] initWithTitle: @"Done"

message: @"Finish playing the recording!"

delegate: nil

cancelButtonTitle:@"OK"

otherButtonTitles:nil];

[alert show];

}


Compile and Run Your App

You can test audio recording and playback using a physical device or software simulator. If you test the app using actual device (e.g. iPhone), the audio being recorded comes from the device connected by the built-in microphone or headset microphone. On the
other hand, if you test the app by using the Simulator, the audio comes from the system’s default audio input device as set in the System Preference.

So go ahead to compile and run the app! Tap “Record” button to start recording. Say something, tap the “Stop” button and then select the “Play” button to listen the playback.



AudioDemo App

For your reference, you can download the complete source code from here. Feel free to leave me comment if you have any questions.

This post is contributed by Yiqi Shi and Raymond from Purple Development. Yiqi and Raymond are independent iOS developers and have recently released Voice
Memo Wifi that allows users to record voice memo and share it over WiFi.
转自:http://www.codeproject.com/Articles/770577/From-Cplusplus-to-Objective-C-A-quick-guide-for-pr
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: