Building an Audio Recorder and Player App in .NET MAUI
Tags: dotnetmaui, development, mobile
Published: 2023-01-12 12:45:38

---
title: Building an Audio Recorder and Player App in .NET MAUI
published: true
date: 2023-01-12 10:58:42 UTC
tags: dotnetmaui, development, mobile
canonical_url: https://www.syncfusion.com/blogs/post/building-an-audio-recorder-and-player-app-in-net-maui.aspx
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/izesv34v70jq7c7zyuz4.png
---
In this blog, you will learn how to develop an audio recorder and player in .NET MAUI. The audio player will record and play audio files.

This application can be deployed and used on both Android and iOS.

Let’s get started!

## Prerequisites

**Tool** : [Visual Studio 2022](https://visualstudio.microsoft.com/vs/ "Visual Studio")

**Supported Platform:** Android and iOS

**Supported OS:** Android (7.0 and above) and iOS (v12 and above)

## Developing audio recorder and player app

### Step 1: Add required permissions in both platforms.

To record audio and save it in a device, the application will have to access the device’s audio input and storage. For that, we need to grant the following permissions:

- RECORD\_AUDIO,
- READ\_EXTERNAL\_STORAGE
- WRITE\_EXTERNAL\_STORAGE

**Note:** In iOS, you can’t add storage permissions. It will always return Granted when checked and requested.

In Android, add the following code to the **AndroidManifest.xml** file.

```xml
<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" />

```

In iOS, add the following code to the Info.plist file.

```xml
<key>NSMicrophoneUsageDescription</key>
<string>The audio recorder app wants to use your microphone to record audio.</string>
```

### Step 2: Create a service for recording and playing the audio.

There is no direct support for recording audio and playing it in .NET MAUI. So, we must create a service in the native platform for recording and playing the audio files.

Before creating a service class, create an interface for invoking the native methods.

Refer to the following code.

```csharp
public interface IAudioPlayer
{
    void PlayAudio(string filePath);
    void Pause();
    void Stop();
    string GetCurrentPlayTime();
    bool CheckFinishedPlayingAudio();
}
public interface IRecordAudio
{
    void StartRecord();
    string StopRecord();
    void PauseRecord();
    void ResetRecord();
}
```

Then, create the service to record and play audio on both platforms.

#### Audio recorder service for Android

Reference the following methods and properties to create an audio recorder service for Android:

- Create an instance of **MediaRecorder** class, which will be used to record the audio.
- **SetAudioSource()**: Specify which hardware device to use to capture the audio input.
- **SetOutputFile()**: Specify the name of the output audio file.
- **Prepare():** Initialize the audio recorder.
- **Start():** Start recording the audio.
- **Reset():** Discard the recorded audio and resets the recorder.
- **Pause():** Pause the recording in the current running position.
- **Resume():** Resume recording from the paused position.
- **Stop():** Stop the audio recording.

Refer to the following code.

```csharp
public class RecordAudio : IRecordAudio
{
   #region Fields
   private MediaRecorder mediaRecorder;
   private string storagePath;
   private bool isRecordStarted = false;
   #endregion
   #region Methods
   
   public void StartRecord()
   {
     if (mediaRecorder == null)
     {
         SetAudioFilePath();
         mediaRecorder = new MediaRecorder();
         mediaRecorder.Reset();
         mediaRecorder.SetAudioSource(AudioSource.Mic);
         mediaRecorder.SetOutputFormat(OutputFormat.AacAdts);
         mediaRecorder.SetAudioEncoder(AudioEncoder.Aac);
         mediaRecorder.SetOutputFile(storagePath);
         mediaRecorder.Prepare();
         mediaRecorder.Start();
     }
     else
     {
         mediaRecorder.Resume();
     }
     isRecordStarted = true;
   }
   public void PauseRecord()
   {
       if (mediaRecorder == null)
       {
           return;
        }
       mediaRecorder.Pause();
       isRecordStarted = false;
   }
   public void ResetRecord()
   {
      if (mediaRecorder != null)
      {
         mediaRecorder.Resume();
         mediaRecorder.Reset();
      }
      mediaRecorder = null;
      isRecordStarted = false;
   }
   public string StopRecord()
   {
      if (mediaRecorder == null)
      {
         return string.Empty;
      }
      mediaRecorder.Resume();
      mediaRecorder.Stop();
      mediaRecorder = null;
      isRecordStarted = false;
      return storagePath;
  }
  private void SetAudioFilePath()
  {
      string fileName = "/Record_" + DateTime.UtcNow.ToString("ddMMM_hhmmss") + ".mp3";
       var path = Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
       storagePath = path + fileName;
       Directory.CreateDirectory(path);
  }
   #endregion
}
```

#### Audio recorder service for iOS

Now, we create the audio recorder service for the iOS platform using **AVAudioRecorder** :

- Initialize the audio session before trying to record.
- Specify the recording format and location in which to save the recording. The recording format is specified as an entry from NSDictionary with two NSObject arrays containing the keys and values of the format.
- Call the **Record** method when ready to initiate recording the audio.
- When finished recording, call the **Stop()** method on the recorder.

Refer to the following code.

```csharp
public class RecordAudio : IRecordAudio
{
   AVAudioRecorder recorder;
   NSUrl url;
   NSError error;
   NSDictionary settings;
   string audioFilePath;
   public RecordAudio()
   {
      InitializeAudioSession();
   }
   private bool InitializeAudioSession()
   {
      var audioSession = AVAudioSession.SharedInstance();
      var err = audioSession.SetCategory(AVAudioSessionCategory.PlayAndRecord);
      if (err != null)
      {
         Console.WriteLine("audioSession: {0}", err);
          return false;
      }
      err = audioSession.SetActive(true);
      if (err != null)
      {
         Console.WriteLine("audioSession: {0}", err);
         return false;
      }
       return false;
    }
    public void PauseRecord()
    {
       recorder.Pause();
    }
    public void ResetRecord()
    {
       recorder.Dispose();
       recorder = null;
    }
    public void StartRecord()
    {
      if (recorder == null)
       {
          string fileName = "/Record_" + DateTime.UtcNow.ToString("ddMMM_hhmmss") + ".wav";
          var docuFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
          audioFilePath = docuFolder + fileName;
          url = NSUrl.FromFilename(audioFilePath);
          NSObject[] values = new NSObject[]
          {
              NSNumber.FromFloat(44100.0f), 
              NSNumber.FromInt32((int)AudioToolbox.AudioFormatType.LinearPCM), 
              NSNumber.FromInt32(2), 
              NSNumber.FromInt32(16), 
              NSNumber.FromBoolean(false),
              NSNumber.FromBoolean(false) 
          };
          NSObject[] key = new NSObject[]
          {
              AVAudioSettings.AVSampleRateKey,
              AVAudioSettings.AVFormatIDKey,
              AVAudioSettings.AVNumberOfChannelsKey,
              AVAudioSettings.AVLinearPCMBitDepthKey,
              AVAudioSettings.AVLinearPCMIsBigEndianKey,
              AVAudioSettings.AVLinearPCMIsFloatKey
          };
          settings = NSDictionary.FromObjectsAndKeys(values, key);
          recorder = AVAudioRecorder.Create(url, new AudioSettings(settings), out error);
          recorder.PrepareToRecord();
          recorder.Record();
      }
      else
      {
         recorder.Record();
      }
   }
   public string StopRecord()
   {
       if (recorder == null)
       {
          return string.Empty;
       }
       recorder.Stop();
       recorder = null;
       return audioFilePath;
  }
}
```

Now, let’s implement an audio player service for playing the recorded audio on both platforms.

#### Audio player service for Android

Follow these steps to create an audio-playing service for Android:

1. Create an instance of the **MediaPlayer** class to play the audio file.
2. Provide the file path of the audio file to the **MediaPlayer** instance through the **SetDataSource** method.
3. After setting the data source, prepare the media player by calling the **Prepare** method.
4. Once the media player is prepared, start playing the audio using the **Start** method.

Refer to the following code.

```csharp
public class AudioPlayer : IAudioPlayer
{
    #region Fields
    private MediaPlayer _mediaPlayer;
    private int currentPositionLength = 0;
    private bool isPrepared;
    private bool isCompleted;
    #endregion
    
    #region Methods
    public void PlayAudio(string filePath)
    {
      if (_mediaPlayer != null && !_mediaPlayer.IsPlaying)
      {
         _mediaPlayer.SeekTo(currentPositionLength);
         currentPositionLength = 0;
         _mediaPlayer.Start();
      }
      else if (_mediaPlayer == null || !_mediaPlayer.IsPlaying)
      {
         try
         {
            isCompleted = false;
            _mediaPlayer = new MediaPlayer();
            _mediaPlayer.SetDataSource(filePath);
            _mediaPlayer.SetAudioStreamType(Stream.Music);
            _mediaPlayer.PrepareAsync();
            _mediaPlayer.Prepared += (sender, args) =>
            {
               isPrepared = true;
               _mediaPlayer.Start();
            };
            _mediaPlayer.Completion += (sender, args) =>
            {
               isCompleted = true;
            };
         }
         catch (Exception e)
         {
            _mediaPlayer = null;
         }
      }
    }
    public void Pause()
    {
       if (_mediaPlayer != null && _mediaPlayer.IsPlaying)
       {
          _mediaPlayer.Pause();
          currentPositionLength = _mediaPlayer.CurrentPosition;
       }
    }
    public void Stop()
    {
      if (_mediaPlayer != null)
      {
         if (isPrepared)
         {
            _mediaPlayer.Stop();
           _mediaPlayer.Release();
           isPrepared = false;
         }
         isCompleted = false;
         _mediaPlayer = null;
      }
  }
  public string GetCurrentPlayTime()
  {
     if (_mediaPlayer != null)
     {
       var positionTimeSeconds = 
       double.Parse(_mediaPlayer.CurrentPosition.ToString());
       positionTimeSeconds = positionTimeSeconds / 1000;
       TimeSpan currentTime = TimeSpan.FromSeconds(positionTimeSeconds);
       string currentPlayTime = string.Format("{0:mm\\:ss}", currentTime);
       return currentPlayTime;
     }
     return null;
  }
  public bool CheckFinishedPlayingAudio()
  {
     return isCompleted;
  }
  #endregion
}
```

#### Audio player service for iOS

Create an audio playing service in iOS using the **AVPlayer** class:

1. Configure the audio file to play through the **AVPlayerItem** built-in class.
2. Call the **Play** method to start the audio playing **.**

Refer to the following code.

```csharp
public class AudioPlayer : IAudioPlayer
{
    AVPlayer _player;
    NSObject notificationHandle;
    NSUrl url;
    private bool isFinishedPlaying;
    private bool isPlaying;
    
    public bool IsPlaying
    {
       get { return isPlaying; }
       set
       {
          if (_player.Rate == 1 && _player.Error == null)
           isPlaying = true;
          else
           isPlaying = false;
       }
    }
    public AudioPlayer()
    {
       RegisterNotification();
    }
    ~AudioPlayer()
    {
      UnregisterNotification();
    }
    public void PlayAudio(string filePath)
    {
      isFinishedPlaying = false;
      if (_player == null)
      {
        url = NSUrl.FromString(filePath);
        AVPlayerItem avPlayerItem = new AVPlayerItem(URL);
        _player = new AVPlayer(avPlayerItem);
        _player.AutomaticallyWaitsToMinimizeStalling = false;
        _player.Volume = 1;
        _player.Play();
        IsPlaying = true;
        isFinishedPlaying = false;
      }
      else if (_player != null && !IsPlaying)
      {
         _player.Play();
         IsPlaying = true;
         isFinishedPlaying = false;
      }
   }
   public void Pause()
   {
     if (_player != null && IsPlaying)
     {
       _player.Pause();
       IsPlaying = false;
     }
   }
   public void Stop()
   {
     if (_player != null)
     {
       _player.Dispose();
       IsPlaying = false;
       _player = null;
     }
   }
   public string GetCurrentPlayTime()
   {
     if (_player != null)
     {
       var positionTimeSeconds = _player.CurrentTime.Seconds;
       TimeSpan currentTime = TimeSpan.FromSeconds(positionTimeSeconds);
       string currentPlayTime = string.Format("{0:mm\\:ss}", currentTime);
       return currentPlayTime;
     }
     return null;
   }
   public bool CheckFinishedPlayingAudio()
   {
     return isFinishedPlaying;
   }
   private void RegisterNotification()
   {
     notificationHandle = NSNotificationCenter.DefaultCenter.AddObserver(AVPlayerItem.DidPlayToEndTimeNotification, HandleNotification);
   }
   private void UnregisterNotification()
   {
      NSNotificationCenter.DefaultCenter.RemoveObserver(notificationHandle);
   }
   private void HandleNotification(NSNotification notification)
   {
      isFinishedPlaying = true;
      Stop();
   }
}
```
### Step 3: Creating a model.

Create a model class to show the recorded audio files in a list. Refer to the following code.

```csharp
public class Audio : INotifyPropertyChanged
{
    #region Private
    private bool isPlayVisible;
    private bool isPauseVisible;
    private string currentAudioPostion;
    #endregion
    
    #region Constructor
    public Audio()
    {
       IsPlayVisible = true;
    }
    #endregion
    
    #region Properties
    public string AudioName { get; set; }
    public string AudioURL { get; set; }
    public string Caption { get; set; }
    public bool IsPlayVisible
    {
       get { return isPlayVisible; }
       set
       {
         isPlayVisible = value;
         OnPropertyChanged();
         IsPauseVisble = !value;
       }
    }
    public bool IsPauseVisble
    {
       get { return isPauseVisible; }
       set { isPauseVisible = value; OnPropertyChanged(); }
    }
    public string CurrentAudioPosition
    {
       get { return currentAudioPostion; }
       set
       {
          if (string.IsNullOrEmpty(currentAudioPostion))
          {
             currentAudioPostion = string.Format("{0:mm\\:ss}", new TimeSpan());
          }
          else
          {
             currentAudioPostion = value;
          }
          OnPropertyChanged();
      }
    }
    #endregion
}
```

In the code, the **CurrentAudioPosition** property helps us to display the playing audio time.

### Step 4: Creating the UI.

We are going to create a simple UI for showing recorded audio files and for recording audio. For this, we will be using Syncfusion’s ListView for .NET MAUI. Install the [.NET MAUI ListView NuGet package](https://www.nuget.org/packages/Syncfusion.Maui.ListView/ ".NET MAUI ListView NuGet package"), and then include it in the application.

The following XAML code will display the recorded audio in Syncfusion’s .NET MAUI ListView control.

```xml
<syncfusion:SfListView
   x:Name="AudioList"
     Grid.Row="0"
     Grid.ColumnSpan="2"
     Margin="0,8"
     IsVisible="true"
     ItemsSource="{Binding Audios}"
     SelectionMode="None">
     <syncfusion:SfListView.ItemTemplate>
       <DataTemplate>
         <ViewCell>
           <Grid
               x:Name="PlayAudioGrid"
                 Margin="0,4,0,12"
                 BackgroundColor="Transparent"
                 HeightRequest="60">
                 <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="50" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="50" />
                    <ColumnDefinition Width="80" />
                </Grid.ColumnDefinitions>
                <Button
                     Grid.Column="0"
                     Padding="0"
                     BackgroundColor="Transparent"
                     Command="{Binding Path=BindingContext.PlayAudioCommand, Source={x:Reference mainPage}}"
                     CommandParameter="{Binding .}"
                     FontFamily="AudioIconFonts"
                     FontSize="22"
                     IsVisible="{Binding IsPlayVisible}"
                     Text="&#xea15;"
                     TextColor="Black" />
                <Button
                     Grid.Column="0"
                     Padding="0"
                     BackgroundColor="Transparent"
                     BorderColor="LightGray"
                     Command="{Binding Path=BindingContext.PauseAudioCommand, Source={x:Reference mainPage}}"
                     CommandParameter="{Binding .}"
                     FontFamily="AudioIconFonts"
                     FontSize="22"
                     IsVisible="{Binding IsPauseVisble}"
                     Text="&#xea16;"
                     TextColor="Black" />
                 <Label
                     Grid.Column="1"
                     FontSize="14"
                     Text="{Binding AudioName}"
                     TextColor="Black"
                     VerticalTextAlignment="Center" />
                 <Label
                     Grid.Column="2"
                     Margin="0,0,12,0"
                     FontSize="14"
                     IsVisible="{Binding IsPauseVisble}"
                     Text="{Binding CurrentAudioPosition}"
                     TextColor="Black"
                     VerticalTextAlignment="Center" />
                 <Button
                     Grid.Column="3"
                     BackgroundColor="Transparent"
                     Command="{Binding Path=BindingContext.DeleteCommand, Source={x:Reference mainPage}}"
                     CommandParameter="{Binding}"
                     FontFamily="AudioIconFonts"
                     FontSize="20"
                     Text="&#xe9ac"
                     TextColor="Red" />
         </Grid>
      </ViewCell>
    </DataTemplate>
  </syncfusion:SfListView.ItemTemplate>
</syncfusion:SfListView>
```
The following XAML code is used to design the UI for recording audio.

```xml
<!-- Timer Label -->
<StackLayout
     Grid.Row="2"
     Grid.ColumnSpan="2"
     Margin="0,0,0,32"
     VerticalOptions="End">
     <Label
         FontSize="14"
         HorizontalTextAlignment="Center"
         IsVisible="{Binding IsRecordingAudio}"
         Text="Recording…"
         TextColor="#7D898F" />
     <Label
         FontSize="60"
         HorizontalTextAlignment="Center"
         IsVisible="{Binding IsRecordingAudio}"
         Text="{Binding TimerLabel}"
         TextColor="Black" />
</StackLayout>
   
<!-- Button Setup -->
<Grid
    Grid.Row="3"
    Grid.ColumnSpan="2"
    ColumnSpacing="60">
    <Grid.ColumnDefinitions>
         <ColumnDefinition Width="*" />
         <ColumnDefinition Width="*" />
         <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
         
    <!-- Retry -->
    <Grid Grid.Column="0" RowDefinitions="auto,auto">
       <Button
            Grid.Row="0"
            BackgroundColor="LightGray"
            BorderColor="#5F49FF"
            BorderWidth="1"
            Command="{Binding ResetCommand}"
            CornerRadius="25"
            FontFamily="AudioIconFonts"
            FontSize="22"
            HeightRequest="50"
            IsEnabled="{Binding IsRecordingAudio}"
            Text="&#xe900;"
            TextColor="#5F49FF"
            WidthRequest="50">
        <Button.Triggers>
             <DataTrigger
                  Binding="{Binding IsRecordingAudio}"
                  TargetType="Button"
                  Value="False">
                  <Setter Property="TextColor" Value="Gray" />
                  <Setter Property="BorderColor" Value="Gray" />
              </DataTrigger>
        </Button.Triggers>
     </Button>
     <Label
         Grid.Row="1"
         HorizontalOptions="Center"
         Text="Retry" />
    </Grid>
       
    <!-- Play -->
    <Grid
        Grid.Column="1"
        HorizontalOptions="CenterAndExpand"
        RowDefinitions="auto,auto">
        <!-- Record Button -->
        <Button
            Grid.Row="0"
            BackgroundColor="Red"
            BorderColor="Red"
            BorderWidth="1"
            Command="{Binding RecordCommand}"
            CornerRadius="25"
            FontFamily="AudioIconFonts"
            FontSize="22"
            HeightRequest="50"
            IsVisible="{Binding IsRecordButtonVisible}"
            Text="&#xe91e;"
            TextColor="White"
            WidthRequest="50" />
        <Label
            Grid.Row="1"
            HorizontalOptions="Center"
            IsVisible="{Binding IsRecordButtonVisible}"
            Text="Record" />
          
         <!-- Pause Button -->
         <Button
             Grid.Row="0"
             BackgroundColor="Green"
             BorderColor="Green"
             BorderWidth="1"
             Command="{Binding PauseCommand}"
             CornerRadius="25"
             FontFamily="AudioIconFonts"
             FontSize="22"
             HeightRequest="50"
             IsVisible="{Binding IsPauseButtonVisible}"
             Text="&#xea1d;"
             TextColor="White"
             WidthRequest="50" />
         <Label
             Grid.Row="1"
             HorizontalOptions="Center"
             IsVisible="{Binding IsPauseButtonVisible}"
             Text="Pause" />
               
          <!-- Resume Button -->
          <Button
              Grid.Row="0"
              BackgroundColor="Red"
              BorderColor="Red"
              BorderWidth="1"
              Command="{Binding RecordCommand}"
              CornerRadius="25"
              FontFamily="AudioIconFonts"
              FontSize="22"
              HeightRequest="50"
              IsVisible="{Binding IsResumeButtonVisible}"
              Text="&#xea1c;"
              TextColor="White"
              WidthRequest="50" />
          <Label
               Grid.Row="1"
               HorizontalOptions="Center"
               IsVisible="{Binding IsResumeButtonVisible}"
               Text="Resume" />
    </Grid>
            
    <!-- Stop -->
    <Grid Grid.Column="2" RowDefinitions="auto,auto">
       <Button
           Grid.Row="0"
           BackgroundColor="LightGray"
           BorderColor="#5F49FF"
           BorderWidth="1"
           Command="{Binding StopCommand}"
           CornerRadius="25"
           FontFamily="AudioIconFonts"
           FontSize="22"
           HeightRequest="50"
           IsEnabled="{Binding IsRecordingAudio}"
           Text="&#xea1e;"
           TextColor="#5F49FF"
           WidthRequest="50">
          <Button.Triggers>
            <DataTrigger
                Binding="{Binding IsRecordingAudio}"
                TargetType="Button"
                Value="False">
                <Setter Property="TextColor" Value="Gray" />
                <Setter Property="BorderColor" Value="Gray" />
            </DataTrigger>
          </Button.Triggers>
       </Button>
       <Label
           Grid.Row="1"
           HorizontalOptions="Center"
           Text="Stop" />
  </Grid>
</Grid>
```

### Step 5: Register dependency injection to access the objects in the constructor.

Dependency injection is a way in which an object (client) receives other objects (services) that depend on it. To learn more about using dependency injection in .NET MAUI, refer to the blog [Learn How to Use Dependency Injection in .NET MAUI](https://www.syncfusion.com/blogs/post/learn-how-to-use-dependency-injection-in-net-maui.aspx "Blog: Learn How to Use Dependency Injection in .NET MAUI").

Refer to the following code to register the dependency injection services. First, we must add the necessary services. Then, we can directly access the objects in the desired class constructors. Therefore, we can access the **AudioPlayerService** and **RecordAudioService** objects in the ViewModel.

```csharp
public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder
         .UseMauiApp<App>()
         .ConfigureFonts(fonts =>
         {
	     fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
	     fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
             fonts.AddFont("AudioIconFonts.ttf", "AudioIconFonts");
         });
     #if ANDROID || IOS
        builder.Services.AddTransient<IAudioPlayerService, AudioPlayerService>();
        builder.Services.AddTransient<IRecordAudioService, RecordAudioService>();
     #endif
        builder.Services.AddTransient<MainPage>();
        builder.Services.AddTransient<AppShell>();
        builder.ConfigureSyncfusionListView();
        return builder.Build();
}
```
### Step 6: Creating a ViewModel.

We have followed the MVVM (model-view-viewmodel) structure to develop this application. So, we need to create a ViewModel ( **MainPageViewModel.cs** ) file for recording and playing audio. In the ViewModel, we generate an audio collection to bind the data for recorded audio.

#### Properties in ViewModel class

- **recordTime, playTimer** : The timer properties used in the UI when we play or record an audio.
- **IsRecordingAudio:** Controls the visibility of the reset and stop options.
- **IsPauseButtonVisible** : Controls the visibility of the Pause button in the UI.
- **IsRecordButtonVisible** : Controls the visibility of the Record button.
- **IsResumeButtonVisible** : Controls the visibility of the Resume button.
- **audios** : The collection of all the recorded audio files to be displayed in a list view.
- **recordAudioService, audioPlayerService:** These interface properties invoke the native platform-specific code.

The following code examples demonstrate the audio recorder.

Use the following code to initiate the recorder. We must invoke the dependency service method **recordAudio.StartRecord()** to start the recorder.

**Note:** Only if the permissions are granted can we start the recorder.

```csharp
private async void StartRecording()
{
    if (!IsRecordingAudio)
    {
       var permissionStatus = await RequestandCheckPermission();
       if (permissionStatus == PermissionStatus.Granted)
       {
          IsRecordingAudio = true;
          IsPauseButtonVisible = true;
          recordAudio.StartRecord();
          IsRecordButtonVisible = false;
          isRecord = true;
          timerValue = new TimeSpan(0, 0, -1);
          recordTimer.Start();
       }
       else
       {
          IsRecordingAudio = false;
          IsPauseButtonVisible = false;
       }
   }
   else
   {
      ResumeRecording();
   }
}
```

Pause the recorder using the **recordAudio.PauseRecord()** platform-specific method.

```csharp
private void PauseRecording()
{
    isRecord = false;
    IsPauseButtonVisible = false;
    IsResumeButtonVisible = true;
    recordAudio.PauseRecord();
}
```

The following method is used to continue the recording from a paused position.

```csharp
private void ResumeRecording()
{
   recordAudio.StartRecord();
   IsResumeButtonVisible = false;
   IsPauseButtonVisible = true;
   isRecord = true;
}
```

Use the following code to reset the recorder and start it from the initial position. Use the platform-specific code recordAudio.ResetRecord() to reset the recorder.

```csharp
private void ResetRecording()
{
   recordAudio.ResetRecord();
   timerValue = new TimeSpan();
   TimerLabel = string.Format("{0:mm\\:ss}", timerValue);
   IsRecordingAudio = false;
   IsPauseButtonVisible = false;
   IsResumeButtonVisible = false;
   StartRecording();
}
```

To stop the recorder, use the platform-specific code recordAudio.StopRecord().

```csharp
private async void StopRecording()
{
   IsPauseButtonVisible = false;
   IsResumeButtonVisible = false;
   IsRecordingAudio = false;
   IsRecordButtonVisible = true;
   timerValue = new TimeSpan();
   recordTimer.Stop();
   RecentAudioFilePath = recordAudio.StopRecord();
   await App.Current.MainPage.DisplayAlert("Alert", "Audio has been recorded", "Ok");
   TimerLabel = string.Format("{0:mm\\:ss}", timerValue);
   SendRecording();
}
private void SendRecording()
{
   Audio recordedFile = new Audio() { AudioURL = RecentAudioFilePath };
   if (recordedFile != null)
   {
      recordedFile.AudioName = Path.GetFileName(RecentAudioFilePath);
      Audios.Insert(0, recordedFile);
   }
}
```

The following code is used to get permission to record

```csharp
public async Task<PermissionStatus> RequestandCheckPermission()
{
    PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.StorageWrite>();
    if (status != PermissionStatus.Granted)
        await Permissions.RequestAsync<Permissions.StorageWrite>();
  
    status = await Permissions.CheckStatusAsync<Permissions.Microphone>();
    if (status != PermissionStatus.Granted)
        await Permissions.RequestAsync<Permissions.Microphone>();
              PermissionStatus storagePermission = await Permissions.CheckStatusAsync<Permissions.StorageWrite>();
              PermissionStatus microPhonePermission = await Permissions.CheckStatusAsync<Permissions.Microphone>();
              if (storagePermission == PermissionStatus.Granted && microPhonePermission == PermissionStatus.Granted) 
              {
                  return PermissionStatus.Granted;
              }
    return PermissionStatus.Denied;
}

```

The following code examples demonstrate the audio player.

We invoke the platform-specific method audioPlayer.PlayAudio(audioFilePath) to play the audio.

```csharp
private void StartPlayingAudio(object obj)
{
   if (audioFile != null && audioFile != (Audio)obj)
   {
       AudioFile.IsPlayVisible = true;
       StopAudio();
   }
   if (obj is Audio)
   {
       audioFile = (Audio)obj;
       audioFile.IsPlayVisible = false;
       string audioFilePath = AudioFile.AudioURL;
       audioPlayer.PlayAudio(audioFilePath);
       SetCurrentAudioPosition();
   }
}
```

Use the following method to pause the audio using the platform-specific method **audioPlayer.Pause()**.

```csharp
private void PauseAudio(object obj)
{
   if (obj is Audio)
   {
      var audiophile = (Audio)obj;
      audioFile.IsPlayVisible = true;
      audioPlayer.Pause();
   }
}
```

Using the method **audioPlayer.Stop()** to stop the audio in the following code.

```csharp
public void StopAudio()
{
   if (AudioFile != null)
   {
      audioPlayer.Stop();
      playTimer.Stop();
   }
}
```
Use the following code to get the current position of the audio and display it in the UI.

```csharp
private void SetCurrentAudioPosition()
{
   playTimer.Interval = new TimeSpan(0, 0, 0, 0, 250);
   playTimer.Tick += (s, e) =>
   {
     if (AudioFile != null)
     {
        AudioFile.CurrentAudioPosition = audioPlayer.GetCurrentPlayTime();
        bool isAudioCompleted = audioPlayer.CheckFinishedPlayingAudio();
   	if (isAudioCompleted)
        {
           AudioFile.IsPlayVisible = true;
           playTimer.Stop();
        }
     }
  };
  playTimer.Start();
}
```

## Output

The following is a screenshot of the application.

![Audio player and recorder app in .NET MAUI](https://www.syncfusion.com/blogs/wp-content/uploads/2023/01/Audio-Output.png)

## Resources

For more details, refer to the GitHub project [.NET MAUI Audio Recorder and Player](https://github.com/SyncfusionExamples/dotnet-maui-audio-recorder-and-player- ".NET MAUI Audio Recorder and Player GitHub demo").

## Conclusion

I hope you now have a clear idea of how to develop a .NET MAUI application to record and play audio files in your Android and iOS phones. Try the project sample and share your feedback in the comments section below.

Syncfusion’s [.NET MAUI controls](https://www.syncfusion.com/maui-controls "Syncfusion .NET MAUI controls") were built from scratch using .NET MAUI, so they feel like framework controls. They are fine-tuned to work with a huge volume of data. Use them to build better cross-platform mobile and desktop apps!

For current customers, the new Essential Studio version is available for download from the [License and Downloads](https://www.syncfusion.com/account/downloads "Syncfusion License and Downloads Page") page. If you are not yet a Syncfusion customer, you can always download [our free evaluation](https://www.syncfusion.com/downloads/maui/confirm "Free evaluation of Syncfusion Essential Studio for .NET MAUI") to see all our controls in action.

For questions, you can contact us through our [support forum](https://www.syncfusion.com/forums "Syncfusion Support Forum"), [support portal](https://support.syncfusion.com/ "Syncfusion Support Portal"), or [feedback portal](https://www.syncfusion.com/feedback/maui "Syncfusion Feedback Portal"). We are always happy to assist you!

## Reference

1. **Android** :
  - [Android Audio](https://learn.microsoft.com/en-us/xamarin/android/app-fundamentals/android-audio "Android Audio documentation")
2. **iOS** :
  - [AVAudioPlayer Class](https://learn.microsoft.com/en-us/dotnet/api/avfoundation.avaudioplayer?view=xamarin-ios-sdk-12 "AVAudioPlayer Class Documentation")
  - [AVAudioRecorder Class](https://learn.microsoft.com/en-us/dotnet/api/avfoundation.avaudiorecorder?view=xamarin-ios-sdk-12 "AVAudioRecorder Class Documentation")

## Related blogs

- [Syncfusion .NET MAUI 2023 Roadmap](https://www.syncfusion.com/blogs/post/syncfusion-net-maui-2023-roadmap.aspx "Blog: Syncfusion .NET MAUI 2023 Roadmap")
- [Authenticate the .NET MAUI App with Azure AD](https://www.syncfusion.com/blogs/post/authenticate-the-net-maui-app-with-azure-ad.aspx "Blog: Authenticate the .NET MAUI App with Azure AD")
- [Introducing the Sixth Set of .NET MAUI Controls](https://www.syncfusion.com/blogs/post/introducing-the-sixth-set-of-net-maui-controls.aspx "Blog: Introducing the Sixth Set of .NET MAUI Controls")
- [Create Project Planning and Resource Management Calendar in .NET MAUI](https://www.syncfusion.com/blogs/post/create-project-planning-and-resource-management-calendar-in-net-maui.aspx "Blog: Create Project Planning and Resource Management Calendar in .NET MAUI")