Xon*_*hiz 7 c# xamarin.android xamarin microsoft-cognitive
我正在构建一个测试应用程序来通过身份验证用户Microsoft's Cognitive Speaker Recognition API.这似乎很简单,但正如他们的API文档中所提到的,在创建注册时,我需要发送byte[]我录制的音频文件.现在,因为我使用Xamarin.Android,我能够录制音频并保存.现在,THAT音频的要求非常具体Microsoft's Cognitive Speaker Recognition API.
根据API文档,音频文件格式必须满足以下要求.
Container -> WAV
Encoding -> PCM
Rate -> 16K
Sample Format -> 16 bit
Channels -> Mono
Run Code Online (Sandbox Code Playgroud)
按照这个方法,我成功地录制了音频,在玩了一些和一些Android文档之后,我也能够实现这些设置:
_recorder.SetOutputFormat(OutputFormat.ThreeGpp);
_recorder.SetAudioChannels(1);
_recorder.SetAudioSamplingRate(16);
_recorder.SetAudioEncodingBitRate(16000);
_recorder.SetAudioEncoder((AudioEncoder) Encoding.Pcm16bit);
Run Code Online (Sandbox Code Playgroud)
这符合所需音频文件的大多数标准.但是,我似乎无法以实际的".wav"格式保存文件,我无法验证文件是否实际被PCM编码.
这是我的AXML和MainActivity.cs:Github Gist
我也遵循了这段代码并将其合并到我的代码中:Github Gist
该文件的规格看起来很好,但持续时间是错误的.无论我录制多长时间,它只显示250毫秒,这导致音频太短.
有没有办法做到这一点?基本上我只想Microsoft's Cognitive Speaker Recognition API通过Xamarin.Android 连接.我找不到任何这样的资源来指导自己.
将Audio Recorder插件NuGet包添加到Android项目(如果您使用它们,则添加到任何PCL,netstandard或iOS库).
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
Run Code Online (Sandbox Code Playgroud)
provider 内添加以下内容<application></application>.<provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data>
</provider>
Run Code Online (Sandbox Code Playgroud)
在Resources文件夹中,创建一个名为的新文件夹 xml
在Resources/xml中,创建一个名为的新文件 file_paths.xml
file_paths.xml,添加以下代码,将[您的包名称]替换为Android项目的包Run Code Online (Sandbox Code Playgroud)<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="my_images" path="Android/data/[your package name]/files/Pictures"/> <external-path name="my_movies" path="Android/data/[your package name]/files/Movies" /> </paths>
AudioRecorderService AudioRecorder { get; } = new AudioRecorderService
{
StopRecordingOnSilence = true,
PreferredSampleRate = 16000
});
public async Task StartRecording()
{
AudioRecorder.AudioInputReceived += HandleAudioInputReceived;
await AudioRecorder.StartRecording();
}
public async Task StopRecording()
{
AudioRecorder.AudioInputReceived += HandleAudioInputReceived;
await AudioRecorder.StartRecording();
}
async void HandleAudioInputReceived(object sender, string e)
{
AudioRecorder.AudioInputReceived -= HandleAudioInputReceived;
PlaybackRecording();
//replace [UserGuid] with your unique Guid
await EnrollSpeaker(AudioRecorder.GetAudioFileStream(), [UserGuid]);
}
Run Code Online (Sandbox Code Playgroud)
HttpClient Client { get; } = CreateHttpClient(TimeSpan.FromSeconds(10));
public static async Task<EnrollmentStatus?> EnrollSpeaker(Stream audioStream, Guid userGuid)
{
Enrollment response = null;
try
{
var boundryString = "Upload----" + DateTime.Now.ToString("u").Replace(" ", "");
var content = new MultipartFormDataContent(boundryString)
{
{ new StreamContent(audioStream), "enrollmentData", userGuid.ToString("D") + "_" + DateTime.Now.ToString("u") }
};
var requestUrl = "https://westus.api.cognitive.microsoft.com/spid/v1.0/verificationProfiles" + "/" + userGuid.ToString("D") + "/enroll";
var result = await Client.PostAsync(requestUrl, content).ConfigureAwait(false);
string resultStr = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
if (result.StatusCode == HttpStatusCode.OK)
response = JsonConvert.DeserializeObject<Enrollment>(resultStr);
return response?.EnrollmentStatus;
}
catch (Exception)
{
}
return response?.EnrollmentStatus;
}
static HttpClient CreateHttpClient(TimeSpan timeout)
{
HttpClient client = new HttpClient();
client.Timeout = timeout;
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//replace [Your Speaker Recognition API Key] with your Speaker Recognition API Key from the Azure Portal
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", [Your Speaker Recognition API Key]);
return client;
}
public class Enrollment : EnrollmentBase
{
[JsonConverter(typeof(StringEnumConverter))]
public EnrollmentStatus EnrollmentStatus { get; set; }
public int RemainingEnrollments { get; set; }
public int EnrollmentsCount { get; set; }
public string Phrase { get; set; }
}
public enum EnrollmentStatus
{
Enrolling
Training,
Enrolled
}
Run Code Online (Sandbox Code Playgroud)
将SimpleAudioPlayer插件NuGet包添加到Android项目(如果您使用它们,则添加到任何PCL,netstandard或iOS库).
public void PlaybackRecording()
{
var isAudioLoaded = Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current.Load(AudioRecorder.GetAudioFileStream());
if (isAudioLoaded)
Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current.Play();
}
Run Code Online (Sandbox Code Playgroud)