Records audio on a device's microphone input.
- Available on NuGet: https://www.nuget.org/packages/Plugin.AudioRecorder
- Install into your PCL project and any platform-specific libraries required for your app.
Platform | Supported | Version |
---|---|---|
Xamarin.iOS | Yes | iOS 7+ |
Xamarin.iOS Unified | Yes | iOS 7+ |
Xamarin.Android | Yes | API 16+ |
Windows Phone Silverlight | No | |
Windows Phone RT | No | |
Windows Store RT | No | |
Windows 10 UWP | Yes | 10+ |
Xamarin.Mac | No |
Supports both classic Xamarin.iOS / Xamarin.Android and Xamarin.Forms
The following permissions are required on each platform:
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<key>NSMicrophoneUsageDescription</key>
<string>The [app name] wants to use your microphone to record audio.</string>
You must check the Internet
and Microphone
capabilities in your app's Package.appxmanifest file.
In a controller/activity/page, initialize a new AudioRecorderService
.
Example:
recorder = new AudioRecorderService
{
StopRecordingOnSilence = true, //will stop recording after 2 seconds (default)
StopRecordingAfterTimeout = true, //stop recording after a max timeout (defined below)
TotalAudioTimeout = TimeSpan.FromSeconds (15) //audio will stop recording after 15 seconds
};
More settings and properties are defined below
To begin recording, use the StartRecording ()
and StopRecording ()
methods as shown:
async void RecordButton_Click (object sender, EventArgs e)
{
await RecordAudio ();
}
async Task RecordAudio ()
{
try
{
if (!recorder.IsRecording)
{
await recorder.StartRecording ();
}
else
{
await recorder.StopRecording ();
}
}
catch (Exception ex)
{
...
}
}
In lieu of calling StopRecording ()
, you can also make use of the StopRecordingAfterTimeout
and/or StopRecordingOnSilence
settings, which are explained below.
Once recording has begun, there are two different ways to determine when recording has finished:
To use the Task-based API, you can grab the returned Task
from the call to StartRecording ()
. This allows you to await the result of the Task
, which will complete when recording is complete and return the path to the recorded audio file.
Example:
var recordTask = await recorder.StartRecording ();
... maybe do some other things like toggle your 'mic' button off while recording
//await the returned Task... this will complete once recording has been stopped
var audioFile = await recordTask;
if (audioFile != null) //non-null audioFile indicates audio was successfully recorded
{
//do something with the file
}
The AudioInputReceived
is raised when recording is complete, and the full filepath of the recorded audio file is passed along.
Example:
recorder.AudioInputReceived += Recorder_AudioInputReceived;
...
await recorder.StartRecording ();
...
private async void Recorder_AudioInputReceived(object sender, string audioFile)
{
//do something with the file
}
NOTE: This event is raised on a background thread to allow for further file processing as needed. If the audioFile
is null or empty, no audio was recorded.
--
There are also multiple ways to use the recorded (or recording) audio data:
There are multiple ways to access the recorded audio file path:
- The Task-based API will return the file path when the task completes. The
Task
can be awaited or use standardTask
continuation APIs. - The Event-based API will return the full path to the recorded audio file in the
audioFile
parameter of theAudioInputReceived
event handler. - The
GetAudioFilePath ()
method on theAudioRecorderService
class will return the recorded audio file path.
These will all return null
in the case that no audio has been recorded yet or no audio was recorded/detected in the last recording session.
Once you have the path to the recorded audio file, you can use standard FileStream
operations and/or a cross platform file system abstraction like PCLStorage to get a stream to the file data.
Complete samples demonstrating audio recording and playback of the recorded file are available in the /Samples folder.
It's also possible to get a stream to the recording audio data as it's being recorded, once StartRecording ()
has been called.
To access this readonly stream of audio data, you may call the GetAudioFileStream ()
method. This is useful in the case you want to immediately begin streaming the audio data to a server or other consumer.
NOTE: Since the WAV header is written after recording, once the audio length is known, the provided Stream
data will contain the PCM audio data only and will not contain a WAV header. If your use case requires a WAV header, you can call AudioFunctions.WriteWaveHeader (Stream stream, int channelCount, int sampleRate, int bitsPerSample)
, which will write a WAV header to the stream with an unknown length.
Since GetAudioFileStream ()
will return a Stream
that is also being populated concurrently, it can be useful to know when the recording is complete - the Stream
will continue to grow! This can be accomplished with either the Event-based API or the Task-based API (which is often more useful).
An example of the Task-based API and concurrent writing and reading of the audio data is shown in the sample accompanying the Xamarin.Cognitive.Speech library. This speech client will stream audio data to the server until the AudioRecordTask
completes, signaling that the recording is finished.
-
IsRecording
bool IsRecording
Returns a value indicating if the AudioRecorderService is currently recording audio.
-
StopRecordingAfterTimeout / TotalAudioTimeout
bool StopRecordingAfterTimeout
Gets/sets a value indicating if the AudioRecorderService should stop recording after a certain amount of time. Default is
true
.TimeSpan TotalAudioTimeout
If
StopRecordingAfterTimeout
is set totrue
, thisTimeSpan
indicates the total amount of time to record audio for before recording is stopped. Defaults to 30 seconds. -
StopRecordingOnSilence / AudioSilenceTimeout
bool StopRecordingOnSilence
Gets/sets a value indicating if the AudioRecorderService should stop recording after silence (low audio signal) is detected. Default is
true
.TimeSpan AudioSilenceTimeout
If
StopRecordingOnSilence
is set totrue
, thisTimeSpan
indicates the amount of 'silent' time is required before recording is stopped. Defaults to 2 seconds. -
SilenceThreshold
float SilenceThreshold
Gets/sets a value indicating the signal threshold that determines silence. If the recorder is being over or under aggressive when detecting silence, you can alter this value to achieve different results. Defaults to .2. Value should be between 0 and 1.
- Currently this is only recording in WAV audio format (due to original use case this was developed for).
- Signal detection (
StopRecordingOnSilence
) is not currently working well/at all on UWP.
Contributions are welcome. Feel free to file issues and pull requests on the repo and they'll be reviewed as time permits.
- Created by Nate Rickard
- AudioRecorderService concept and some original code from SmartCoffee by Pierce Boggan
- Audio stream and wave recorder classes adapted from SimplyMobile by Sami M. Kallio
Licensed under the MIT License (MIT). See LICENSE for details.