I'm attempting to get to grips with the basics of capturing audio from a phone and then allowing playback.
Currently I have a 'Start' button and an 'End' button.
The Start button invokes my asynchronous 'CaptureAudio' method, and an 'End button which invokes a 'StopCapture' asynchronous method:
private async void CaptureAudio()
{
_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);
}
private async void StopCapture()
{
await _mediaCaptureManager.StopRecordAsync();
}
I looked at a few samples via MSDN but unfortunately the samples and documentation seemed to fall short of providing a fully working sample code for capturing audio (the MSDN docs give an example of capturing video via the MediaCapture class, and I seen a sample code project on MSDN which I downloaded, which doesn't seem to work as it doesn't build).
What I'm looking to do with this is to have the recorded audio played back again upon user request.
One query I have is whether I must save the recorded audio and save it to the phone's disk, or whether I can simply keep it in memory and then play the audio back from memory.
How should I approach this?
I'm not looking for exact answers, even links to other samples or documentation would help me.
Thanks
The Media capture using capture device sample that I had been using to learn how to record and playback audio actually was of use to me.
It turns out the reason that project wasn't building for me was because of an unrelated VS2013 bug, that I fixed following instructions online (the details are irrelevant to this discussion).
To answer my own question then, the 'MediaCapture' class was the right class to be using. One thing to note is that this class is part of the new Multimedia API that works with both Windows Store apps on Windows 8.1 and also Windows Phone 8.1.
Since there isn't a great deal of code samples around yet, I'll share my own rough code for recording and playing back audio on WP8.1. This code is stripped down to the basics, there is no real error handling or anything here. At the front-end (XAML), I just have two buttons with OnClick events for starting and stopping the audio recording.
Here are my global variables:
private MediaCapture _mediaCaptureManager;
private StorageFile _recordStorageFile;
private bool _recording;
private bool _suspended;
private bool _userRequestedRaw;
private bool _rawAudioSupported;
private TypedEventHandler
<SystemMediaTransportControls, SystemMediaTransportControlsPropertyChangedEventArgs> _mediaPropertyChanged;
To initialize the device in order to record audio, I used this method on app initialisation:
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);
}
Upon a click event on the UI, I then invoked this code to start an audio recording:
private async void CaptureAudio()
{
try
{
Debug.WriteLine("Starting record");
String fileName = AUDIO_FILE_NAME;
_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");
}
catch(Exception e)
{
Debug.WriteLine("Failed to capture audio");
}
}
Upon a separate click event to stop the recording, I invoke this code, which saves the audio recording to a file in the 'VideosLibrary' folder, and then I immediately playback the recording:
/// <summary>
/// Stop recording and play it back
/// </summary>
private async void StopCapture()
{
Debug.WriteLine("Stopping recording");
await _mediaCaptureManager.StopRecordAsync();
Debug.WriteLine("Stop recording successful");
var stream = await _recordStorageFile.OpenAsync(FileAccessMode.Read);
Debug.WriteLine("Recording file opened");
playbackElement1.AutoPlay = true;
playbackElement1.SetSource(stream, _recordStorageFile.FileType);
playbackElement1.Play();
}
I should note that to play back the recording, I had to add a to the XAML in my app, e.g.
<Canvas x:Name="playbackCanvas1">
<MediaElement x:Name="playbackElement1" />
</Canvas>
Another point of note which wasn't obvious from Microsoft's documentation and code samples is that you also need to enable 'Microphone' and 'Videos Library' permissions in the app manifest file. To do that, click on the .appmanifest file from the solution explorer which will be located in the root-level of your project. From there, click the 'Capabilities' tab, and from there you can enable the microphone and videos library.