我正在尝试录制音频并在之后处理它。据我所知,没有统一的API可以用来跨不同平台访问麦克风。我的目标是WASM, UWP和Android。
我的方法是用特定于平台的代码记录音频。
UWP我可以使用如下所述的mediaccapture类:link。我已经实现了这部分,它工作得很好。
Android它也应该是直接的。我可以使用Android.Media.MediaRecorder,如下所示:链接。我不确定如何得到录制的音频文件之后。
对于WASM我在这里完全迷路了。我想我可以使用一些javascript库来记录这里所描述的声音或vmsg库链接。但是我不知道如何将记录的数据转换成c#代码进行进一步处理。
为了更好地理解这个主题,我应该读些什么材料吗?我是否忽略了一些重要的细节?或者有一个简单的方法如何在xamarin录制音频。Android和wasm?更新:我已经使用Android. media . mediarecorder在Android上成功实现了音频捕获,我可以在完成录制后简单地访问文件。
我终于在三个平台(UWP, Android, WASM)上进行了录制。这里的目标是获得原始PCM音频数据,采样率为48 kHz, 1通道,每个采样16位。
UWP:
全球var:
MediaCapture audioCapture = new MediaCapture();
IRandomAccessStream buffer = new InMemoryRandomAccessStream();
记录音频:
public async Task RecordAudio(int recordingLength, uint sampleRate, uint channels, uint bitsPerSample)
{
//initialization
await audioCapture.InitializeAsync(new MediaCaptureInitializationSettings { StreamingCaptureMode = StreamingCaptureMode.Audio });
//encoding setup
MediaEncodingProfile profile = MediaEncodingProfile.CreateWav(AudioEncodingQuality.Auto);
profile.Audio = AudioEncodingProperties.CreatePcm(sampleRate, channels, bitsPerSample);
//start recording
await audioCapture.StartRecordToStreamAsync(profile, buffer);
await Task.Delay(recordingLength * 1000);
//stop recording
await audioCapture.StopRecordAsync();
}
获取PCM数据为字节数组:
public async Task<byte[]> GetPCMData()
{
byte[] data = new byte[buffer.Size];
DataReader dataReader = new DataReader(buffer.GetInputStreamAt(0));
await dataReader.LoadAsync((uint)buffer.Size);
dataReader.ReadBytes(data);
return data;
}
ANDROID:记得先检查麦克风权限。全球var:
byte[] buffer;
AudioRecord recorder;
int bufferLimit;
记录音频:
public async Task RecordAudio(int recordingLength, uint sampleRate, uint channels, uint bitsPerSample)
{
//initialization
// seconds * (number of bytes bytes per 1 sample) * sampleRate
bufferLimit = recordingLength * bitsPerSample/8 * sampleRate;
//encoding setup
ChannelIn channels = Parameters.Channels == 1 ? ChannelIn.Mono : ChannelIn.Stereo;
if (bitsPerSample != 16)
throw new Exception("Unsupported bits per sample value");
recorder = new AudioRecord(
AudioSource.Mic,
(int)sampleRate,
channels,
Android.Media.Encoding.Pcm16bit,
bufferLimit
);
//start recording
buffer = new byte[bufferLimit];
int totalBytesRead = 0;
recorder.StartRecording();
//record until specified amount of bytes was read
while(totalBytesRead < bufferLimit)
{
int bytesRead = recorder.Read(buffer, 0, bufferLimit);
if (bytesRead < 0)
{
throw new Exception(String.Format("Exception code: {0}", bytesRead));
}
else
{
totalBytesRead += bytesRead;
}
}
//stop recording
recorder.Stop();
recorder.Dispose();
}
获取PCM数据为字节数组:
public async Task<byte[]> GetPCMData()
{
return buffer;
}
WASM:
我使用RecordRTC javascript库获取音频数据:
function record(recordingLength, sampleRate, channels) {
navigator.mediaDevices.getUserMedia({
audio: true
}).then(async function (stream) {
//initialization
let recorder = RecordRTC(stream, {
type: 'audio',
mimeType: 'audio/wav',
recorderType: StereoAudioRecorder,
sampleRate: sampleRate,
desiredSampRate: sampleRate,
numberOfAudioChannels: channels
});
//start recording
recorder.startRecording();
const sleep = m => new Promise(r => setTimeout(r, m));
await sleep(recordingLength * 1000);
recorder.stopRecording(function () {
//blob of PCM audio data that can be further processed
let blob = recorder.getBlob();
}
});
});
}
在<<p> strong> WASM 我用blob作为base64字符串从javascript调用c#代码,在c#中进一步处理PCM音频数据的blob(如何从javascript调用c#代码可以在Uno平台文档中找到)。
我知道,这不是最干净的解决方案,但它是一个工作之一。