Recording Audio in Windows Phone 8.1

First Words

This article points to a simple, fast way to record audio in Windows Phone 8.1. As the old Microphone class is no longer available, Windows Phone 8.1 came with new MediaCapture class to consolidate the media recording part for audio and video together. So, why waiting, let’s see how to do it!

Let’s get busy

I jotted a very simple GUI for this that has three simple buttons named “Capture Audio”, “Stop Capture” and “Play Capture”.  And it looks as follows:

CaptureAudio1

If you guys want to have a closer look at the XAML behind, peek a look:

<Page
    x:Class="CaptureSoundTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CaptureSoundTest"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <MediaElement x:Name="playbackElement1" ></MediaElement>
        <Button x:Name="CaptureButton" Content="Capture Audio" HorizontalAlignment="Center" Margin="0,184,0,0" VerticalAlignment="Top" Click="CaptureButton_Click" Width="145"/>
        <Button x:Name="StopCaptureButton" Content="Stop Capture" HorizontalAlignment="Center" Margin="0,284,0,0" VerticalAlignment="Top" Click="StopCaptureButton_Click" Width="145"/>
        <Button x:Name="PlayRecordButton" Content="Play Capture" HorizontalAlignment="Center" Margin="0,380,0,0" VerticalAlignment="Top" Click="PlayRecordButton_Click" Width="145"/>

    </Grid>
</Page>

It’s pretty basic, I didn’t do much here without keeping the buttons in place. There’s a MediaElement named playbackElement1 to play back the recorded video.

Now, it’s time to populate the button events here named CaptureButton_Click, StopCaptureButton_Click and PlayRecordButton_Click

Initializing and Capturing audio

To capture audio, first we need to initialize the recording. Before digging into that, let’s just initialize some variables that we might need on the journey.

private MediaCapture _mediaCaptureManager;
private StorageFile _recordStorageFile;
private bool _recording;
private bool _userRequestedRaw;
private bool _rawAudioSupported;

The MediaCapture class here is the one responsible here to capture audio and video both here. And StorageFile instance will help us store, locate and play the recorded media on our device.

So, let’s have a look how our recording initialization method looks like:

private async void InitializeAudioRecording()
{

   _mediaCaptureManager = new MediaCapture();
   var settings = new MediaCaptureInitializationSettings();
   settings.StreamingCaptureMode = StreamingCaptureMode.Audio;
   settings.MediaCategory = MediaCategory.Other;
   settings.AudioProcessing = (_rawAudioSupported &amp;&amp; _userRequestedRaw) ? AudioProcessing.Raw : AudioProcessing.Default;

   await _mediaCaptureManager.InitializeAsync(settings);

   Debug.WriteLine("Device initialised successfully");

   _mediaCaptureManager.RecordLimitationExceeded += new RecordLimitationExceededEventHandler(RecordLimitationExceeded);
    _mediaCaptureManager.Failed += new MediaCaptureFailedEventHandler(Failed);
}

So, the very first thing done here is the initialization of the MediaCapture class. Every media capture is associated with a MediaCaptureInitializationSettings instance. We’ve set the StreamingCaptureMode to Audio to make sure this is only audio recording rather than video. There were two bool variables declared before named _rawAudioSupported and _userRequestedRaw. Although I didn’t hook them up from GUI, you guys can defintiely try hooking them up from GUI and thus you can give the app a choice to record raw or pointing it to default audio processing.

The next thing to do is initializing the _mediaCaptureManager with the settings provided. I have included two event handlers for RecordingLimitExceeded and Failed. You guys can write your own handlers of course in these cases.

Now, usually you can put the InitializeAudioRecording method where your app initializes. I put it here on MainPage constructor.

Now, let’s capture audio, MediaCapture class made it really easy indeed.

private async void CaptureAudio()
{
   try
   {
     Debug.WriteLine("Starting record");
     String fileName = "record.m4a";

     _recordStorageFile = await KnownFolders.VideosLibrary.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName);

     Debug.WriteLine("Create record file successfully");

     MediaEncodingProfile recordProfile = MediaEncodingProfile.CreateM4a(AudioEncodingQuality.Auto);
     await _mediaCaptureManager.StartRecordToStorageFileAsync(recordProfile, this._recordStorageFile);

     Debug.WriteLine("Start Record successful");

     _recording = true;
    }
    catch (Exception e)
    {
      Debug.WriteLine("Failed to capture audio");
    }
}

If you have a good look on the code you will see we declared a filename first. And then we created a file in our VideosLibrary using KnownFolders.VideosLibrary.CreateFileAsync that actually points to the media and video library of windows phone 8.1 with a given filename and we also gave a CreationCollisionOption.GenerateUniqueName that says it will create a unique name in case of collision. The next thing to do is creating a recording profile using MediaEncodingProfile class and you can get all possible recording profiles for videos and audios from here. I created a M4a audio profile using MediaEncodingProfile.CreateM4a(recordProfile, this._recordStorageFile) method.

All we have left to do is now start the recording, so  let’s go ahead and start the recording. And it’s easy as pie with _mediaCaptureManager.StartRecordToStorageFileAsync(recordProfile, this._recordStorageFile)

Stopping Recording

Stopping the recording is quiet easy too. All you have to do is call _mediaCaptureManager.StopRecordAsync()

private async void StopCapture()
{

     if (_recording)
     {
          Debug.WriteLine("Stopping recording");
          await _mediaCaptureManager.StopRecordAsync();
          Debug.WriteLine("Stop recording successful");
          _recording = false;
     }

}

Playing Recording

Playing a recording kind of consists of two tasks. First we have to open the recorded file and then play it. If you guys remember we used StorageFile _recordStorageFile to define our file that will hold the recording.

private async void PlayRecordedCapture()
{
     if (!_recording)
     {
         var stream = await _recordStorageFile.OpenAsync(FileAccessMode.Read);
         Debug.WriteLine(&quot;Recording file opened&quot;);
         playbackElement1.AutoPlay = true;
         playbackElement1.SetSource(stream, _recordStorageFile.FileType);
         playbackElement1.Play();
     }
}

So, let’s open up the file and assign the resultant stream to a source of a MediaElement on XAML. In this case that one is playBackElement1

 

Voila! You’re done, now you can play your recording. All you have to do now is assign these three methods to proper button events. For the full source please download the demo project above.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s