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:
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 && _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("Recording file opened");
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.