274 lines
7.1 KiB
C#
274 lines
7.1 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.IO;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using UnityEngine;
|
|
|
|
public class MicrophoneInputHuman : MonoBehaviour
|
|
{
|
|
public static MicrophoneInputHuman instance;
|
|
public AudioSource audioSource;
|
|
public int lengthSec = 60;
|
|
private int frequency = 16000;
|
|
private string savePath;
|
|
|
|
|
|
private void Awake()
|
|
{
|
|
instance = this;
|
|
savePath = Application.persistentDataPath + "/audios/micro.wav";
|
|
audioSource = GetComponent<AudioSource>();
|
|
if (!Directory.Exists(Path.GetDirectoryName(savePath)))
|
|
{
|
|
Directory.CreateDirectory(Path.GetDirectoryName(savePath));
|
|
}
|
|
|
|
if (!File.Exists(savePath))
|
|
{
|
|
File.Create(savePath);
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 开始录制
|
|
/// </summary>
|
|
public void OnStartClick()
|
|
{
|
|
Debug.Log("OnStartClick");
|
|
|
|
|
|
if (!Application.HasUserAuthorization(UserAuthorization.Microphone))
|
|
{
|
|
Debug.LogError("无录音权限,获取中,请重新说话");
|
|
MyDebugger.Log("无录音权限,获取中,请重新说话");
|
|
StartCoroutine(RequestMicrophoneAuth());
|
|
return;
|
|
}
|
|
|
|
StartRecord();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 停止录制
|
|
/// </summary>
|
|
public void OnStopClick(Action<string> callback)
|
|
{
|
|
Debug.Log("OnStopClick");
|
|
|
|
int length = StopRecord();
|
|
if (length > 0)
|
|
{
|
|
byte[] file = WavUtility.FromAudioClip(audioSource.clip, savePath, true);
|
|
IFlytekManager.instance.AudioToText(file, str =>
|
|
{
|
|
callback(str);
|
|
});
|
|
}
|
|
else
|
|
{
|
|
MyDebugger.Log("没录音数据");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 播放录音
|
|
/// </summary>
|
|
private void PlayAudio()
|
|
{
|
|
|
|
//读取本地文件播放
|
|
ReadAudioFile(savePath);
|
|
}
|
|
|
|
|
|
public IEnumerator RequestMicrophoneAuth()
|
|
{
|
|
yield return Application.RequestUserAuthorization(UserAuthorization.Microphone);
|
|
}
|
|
|
|
public void StartRecord()
|
|
{
|
|
if (Microphone.devices.Length > 0)
|
|
{
|
|
Debug.Log("开始录音");
|
|
|
|
audioSource.Stop();
|
|
audioSource.loop = false;
|
|
audioSource.mute = true;
|
|
audioSource.clip = Microphone.Start(null, false, lengthSec, frequency);
|
|
|
|
MyDebugger.Log("录音中");
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("无麦克风");
|
|
MyDebugger.Log("无麦克风");
|
|
}
|
|
|
|
}
|
|
|
|
public int StopRecord()
|
|
{
|
|
int length = Microphone.GetPosition(null);
|
|
Microphone.End(null);
|
|
|
|
return length;
|
|
}
|
|
|
|
public bool SaveAudioFile(string filePath, int length)
|
|
{
|
|
if (Microphone.IsRecording(null))
|
|
return false;
|
|
|
|
|
|
|
|
byte[] data = GetClipData(audioSource, length);
|
|
if (data == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
File.WriteAllBytes(filePath, data);
|
|
string infoLog = "total length:" + data.Length + " time:" + audioSource.time + " path:" + filePath;
|
|
Debug.Log(infoLog);
|
|
|
|
return true;
|
|
}
|
|
|
|
public void ReadAudioFile(string filePath)
|
|
{
|
|
byte[] bytes = File.ReadAllBytes(filePath);
|
|
float[] samples = byte2float(bytes);
|
|
|
|
var clip = audioSource.clip;
|
|
audioSource.Stop();
|
|
audioSource.clip = AudioClip.Create(clip.name, samples.Length, clip.channels, clip.frequency, false);
|
|
audioSource.clip.SetData(samples, 0);
|
|
audioSource.mute = false;
|
|
audioSource.Play();
|
|
}
|
|
|
|
byte[] GetClipData(AudioSource source, int length)
|
|
{
|
|
if (length < 10)
|
|
{
|
|
Debug.Log("录音文件太短");
|
|
return null;
|
|
}
|
|
|
|
float[] samples = new float[length];
|
|
source.clip.GetData(samples, 0);
|
|
|
|
byte[] outData = float2byte(samples);
|
|
return outData;
|
|
}
|
|
byte[] float2byte(float[] floats)
|
|
{
|
|
byte[] outData = new byte[floats.Length * 2];
|
|
int reScaleFactor = 32767;
|
|
|
|
for (int i = 0; i < floats.Length; i++)
|
|
{
|
|
short tempShort = (short)(floats[i] * reScaleFactor);
|
|
byte[] tempData = BitConverter.GetBytes(tempShort);
|
|
|
|
outData[i * 2] = tempData[0];
|
|
outData[i * 2 + 1] = tempData[1];
|
|
}
|
|
|
|
return outData;
|
|
}
|
|
|
|
float[] byte2float(byte[] bytes)
|
|
{
|
|
float reScaleFactor = 32768.0f;
|
|
float[] data = new float[bytes.Length / 2];
|
|
for (int i = 0; i < bytes.Length; i += 2)
|
|
{
|
|
short s;
|
|
if (BitConverter.IsLittleEndian) //小端和大端顺序要调整
|
|
s = (short)((bytes[i + 1] << 8) | bytes[i]);
|
|
else
|
|
s = (short)((bytes[i] << 8) | bytes[i + 1]);
|
|
// convert to range from -1 to (just below) 1
|
|
data[i / 2] = s / reScaleFactor;
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
//private IEnumerator CallAudioToString(string fileName,long fileSize)
|
|
//{
|
|
// string ts = GetTimeStampSecond().ToString();
|
|
// var a = new { duration = 200, fileName = fileName, fileSize = fileSize, signa = GetSigna(ts), ts = ts, appId = APPID };
|
|
|
|
// UnityWebRequest request = UnityWebRequest.Post("https://raasr.xfyun.cn/v2/api/upload", JsonConvert.SerializeObject(a));
|
|
// request.uploadHandler.contentType = "application/json";
|
|
|
|
// yield return request.SendWebRequest();
|
|
|
|
// if(!request.isNetworkError && !request.isHttpError)
|
|
// {
|
|
// Debug.Log(request.downloadHandler.text);
|
|
// audioText.text = request.downloadHandler.text;
|
|
// }
|
|
// else
|
|
// {
|
|
// audioText.text = request.downloadHandler.error;
|
|
// }
|
|
//}
|
|
|
|
//private string GetSigna(string ts)
|
|
//{
|
|
// string md5str = MD5(APPID + ts);
|
|
// string hmacStr= HMACSHA1Text(md5str, SecretKey);
|
|
// return hmacStr;
|
|
//}
|
|
/// <summary>
|
|
/// 获取时间戳-单位秒
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private int GetTimeStampSecond()
|
|
{
|
|
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
|
return Convert.ToInt32(ts.TotalSeconds);
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 字符串MD5加密
|
|
/// </summary>
|
|
/// <param name="Text">要加密的字符串</param>
|
|
/// <returns>密文</returns>
|
|
private string MD5(string Text)
|
|
{
|
|
byte[] buffer = Encoding.UTF8.GetBytes(Text);
|
|
System.Security.Cryptography.MD5CryptoServiceProvider check;
|
|
check = new System.Security.Cryptography.MD5CryptoServiceProvider();
|
|
byte[] somme = check.ComputeHash(buffer);
|
|
string ret = "";
|
|
foreach (byte a in somme)
|
|
{
|
|
if (a < 16)
|
|
ret += "0" + a.ToString("X");
|
|
else
|
|
ret += a.ToString("X");
|
|
}
|
|
return ret.ToLower();
|
|
}
|
|
|
|
private string HMACSHA1Text(string text, string key)
|
|
{
|
|
//HMACSHA1加密
|
|
HMACSHA1 hmacsha1 = new HMACSHA1();
|
|
hmacsha1.Key = Encoding.UTF8.GetBytes(key);
|
|
|
|
byte[] dataBuffer = Encoding.UTF8.GetBytes(text);
|
|
byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer);
|
|
|
|
return Convert.ToBase64String(hashBytes);
|
|
}
|
|
}
|