This guide wraps the procedure for the implementation of an Audio Recorder and an Audio Player in Xamarin. This tool has a broad audience with applications having a high emphasis on Multimedia. We are going to proceed Audio Recorder and Player using a DependencyService approach. This is done by creating an Interface with prototypes and describing those in native projects. DependencyService allows apps to call into platform-specific functionality from shared code. This functionality enables Xamarin.Forms apps to achieve anything that a native app can do.
namespace AudioRecorderDemo.Interfaces
{
interface IAudioRecorder
{
void StartRecording();
void StopRecording();
void PlayRecording();
}
}
IOS: In we have AVAudioRecorder class for recording and AVPlayer class for playback.
[assembly: Xamarin.Forms.Dependency(typeof(AudioRecorder))]
namespace AudioRecorderDemo.iOS
{
public class AudioRecorder : IAudioRecorder
{
AVAudioRecorder recorder;
AVPlayer player;
NSError error;
NSUrl url;
NSDictionary settings;
string audioFilePath;
public void StartRecording()
{
var audioSession = AVAudioSession.SharedInstance();
var err = audioSession.SetCategory(AVAudioSessionCategory.PlayAndRecord); s
string fileName = string.Format("Myfile{0}.wav", DateTime.Now.ToString("yyyyMMddHHmmss"));
audioFilePath = Path.Combine(Path.GetTempPath(), fileName);
url = NSUrl.FromFilename(audioFilePath);
NSObject[] values = new NSObject[]
{
NSNumber.FromFloat(44100.0f),
NSNumber.FromInt32 ((int)AudioToolbox.AudioFormatType.LinearPCM),//AVFormat
NSNumber.FromInt32 (2), //Channels
NSNumber.FromInt32 (16), //PCMBitDepth
NSNumber.FromBoolean (false), //IsBigEndianKey
NSNumber.FromBoolean (false) //IsFloatKey
};
NSObject[] keys = new NSObject[]
{
AVAudioSettings.AVSampleRateKey,
AVAudioSettings.AVFormatIDKey,
AVAudioSettings.AVNumberOfChannelsKey,
AVAudioSettings.AVLinearPCMBitDepthKey,
AVAudioSettings.AVLinearPCMIsBigEndianKey,
AVAudioSettings.AVLinearPCMIsFloatKey
};
settings = NSDictionary.FromObjectsAndKeys(values, keys);
recorder = AVAudioRecorder.Create(url, new AudioSettings(settings), out error);
recorder.PrepareToRecord();
recorder.Record();
}
public void StopRecording()
{
recorder.Stop();
var asset = AVAsset.FromUrl(url);
var playerItem = new AVPlayerItem(asset);
player = new AVPlayer(playerItem);
var playerLayer = AVPlayerLayer.FromPlayer(player);
GetController().View.Layer.AddSublayer(playerLayer);
}
public async void PlayRecording()
{
player.Play();
}
private static UIViewController GetController()
{
var vc = UIApplication.SharedApplication.KeyWindow.RootViewController;
while (vc.PresentedViewController != null)
vc = vc.PresentedViewController;
return vc;
}
}
}
Android: In we have AVAudioRecorder class for recording and AVPlayer class for playback.
[assembly: Xamarin.Forms.Dependency(typeof(AudioRecorder))]
namespace AudioRecorderDemo.Droid.DS
{
class AudioRecorder : IAudioRecorder
{
static long Time { get; set; }
MediaRecorder _recorder;
MediaPlayer _player;
string path = "/sdcard/test.3gpp";
public AudioRecorder()
{
_recorder = new MediaRecorder();
_player = new MediaPlayer();
_player.Completion += (sender, e) =>
{
_player.Reset();
};
}
public void StartRecording()
{
try
{
_recorder.SetAudioSource(AudioSource.Mic);
_recorder.SetOutputFormat(OutputFormat.ThreeGpp);
_recorder.SetAudioEncoder(AudioEncoder.AmrNb);
_recorder.SetOutputFile(path);
_recorder.Prepare();
_recorder.Start();
}
catch (Exception e)
{
var str = e.Message;
}
}
public void StopRecording()
{
try
{
_recorder.Stop();
_recorder.Reset();
_player.SetDataSource(path);
}
catch (Exception e)
{
var str = e.Message;
}
}
public async void PlayRecording()
{
_player.Prepare();
Time = _player.Duration;
_player.Looping = true;
_player.Start();
}
}
}
Find the Sample here.