Drastic.AudioRecorder 1.0.2

dotnet add package Drastic.AudioRecorder --version 1.0.2                
NuGet\Install-Package Drastic.AudioRecorder -Version 1.0.2                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Drastic.AudioRecorder" Version="1.0.2" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Drastic.AudioRecorder --version 1.0.2                
#r "nuget: Drastic.AudioRecorder, 1.0.2"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Drastic.AudioRecorder as a Cake Addin
#addin nuget:?package=Drastic.AudioRecorder&version=1.0.2

// Install Drastic.AudioRecorder as a Cake Tool
#tool nuget:?package=Drastic.AudioRecorder&version=1.0.2                

Drastic.AudioRecorder

Drastic.AudioRecorder is a fork of Plugin.AudioRecorder, for .NET Platforms. It has the same API as Plugin.AudioRecorder, apart from the namespace.

Features:

  • Records audio on a device's microphone input
  • Allows access to recorded audio via file or Stream
  • Configurable silence detection to automatically end recording
  • Simple event and Task-based APIs
  • Cross platform AudioPlayer included

Setup

Required Permissions & Capabilities

The following permissions/capabilities are required to be configured on each platform:

Android
<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" />

Additionally, on OS versions Marshmallow and above, you may need to perform a runtime check to ask the user to access their microphone.

Example:

Do this in your main activity or at the point you'll be needing access to record audio:

if (ContextCompat.CheckSelfPermission (this, Manifest.Permission.RecordAudio) != Permission.Granted)
{
	ActivityCompat.RequestPermissions (this, new String [] { Manifest.Permission.RecordAudio }, 1);
}
iOS

For iOS 10 and above, you must set the NSMicrophoneUsageDescription in your Info.plist:

<key>NSMicrophoneUsageDescription</key>
<string>The [app name] wants to use your microphone to record audio.</string>
UWP

You must check the Internet and Microphone capabilities in your app's Package.appxmanifest file.

Usage

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

Recording

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.

Using the Audio Data

Once recording has begun, there are two different ways to determine when recording has finished:

Task-based API

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
}

Event-based API

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:

Accessing the Recorded File

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 standard Task continuation APIs.
  • The Event-based API will return the full path to the recorded audio file in the audioFile parameter of the AudioInputReceived event handler.
  • The GetAudioFilePath () method on the AudioRecorderService 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 file operations (for native/.NET Standard) and/or a cross platform file system abstraction like PCLStorage to get a stream to the file data.

Concurrent Streaming

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.

Properties and Settings

  • 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 to true, this TimeSpan 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 to true, this TimeSpan 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 for your use case, you can alter this value to achieve different results. Defaults to .15. Value should be between 0 and 1.

  • FilePath

    string FilePath
    

    Gets/sets the desired file path. If null it will be set automatically to a temporary file.

  • ConfigureAVAudioSession (iOS only)

    static bool ConfigureAVAudioSession
    

    Gets/sets whether the AudioRecorderService should attempt to control the shared AVAudioSession category. This can be set from the AppDelegate (example) or other iOS-specific class. When set to true, the AudioRecorderService will attempt to set the category to Record before recording, and restore the category to its previous value after recording is complete. This can help this plugin coexist with other media plugins that try to unilaterally set the category. Defaults to false.

Limitations

  • Currently this is only recording in WAV audio format (due to original use case this was developed for).

Contributing

Contributions are welcome. Feel free to file issues and pull requests on the repo and they'll be reviewed as time permits.

Debugging

The easiest way to debug this library is to clone this repo and copy the shared library + platform project (of the platform you're debugging with) into your solution folder, then include the projects in your solution and reference them directly, rather than referencing the NuGet package.

About

License

Licensed under the MIT License (MIT). See LICENSE for details.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-android31.0 is compatible.  net6.0-ios was computed.  net6.0-ios16.1 is compatible.  net6.0-maccatalyst was computed.  net6.0-maccatalyst16.1 is compatible.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net6.0-windows10.0.19041 is compatible.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.2 1,400 5/2/2023
1.0.1 141 5/2/2023
1.0.0 144 5/2/2023