需求:
进入音频录制状态,麦克风一直处于打开(录制状态); 只有当真实收到外部音源时(比如有人说话);才开始将这段音频作为真实录制的音频; 当没人说话2s,就截取这段音频作为有效音频发布出去。
(模仿实时流音频的发送)
1. 百度语音翻译和语音控制。
要求是一段音频流传上去进行处理,这个时候麦克风处于打开,不需要用户去点按钮录制;自动判定有效音频发送。
2.这里就需要用到 Microphone.GetPosition 来做判断
源码如下:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Linq;
using System.IO;namespace nn
{
public class testdemo : MonoBehaviour
{
private enum AudioRecordResultState { start, stop }
[SerializeField] private int maxClipLength = 300;
[HideInInspector] public bool isRecording = false;
private const int RECORD_TIME = 300;//最长录制5分钟private const int ClearAudioTime = 10;//每隔10秒清空1个无效数据;就是没有音源记录的数据
private AudioClip recordedClip;
private int _sampleWindow = 128;
private float recordTimer = 0.0f;private static string[] micArray;
private float limateAudioLevel = 0.1f;
///
/// 当前有记录真实人音了
///
private bool CurrentHaveRecordRealAudio = false;private AudioRecordResultState currentTyp = AudioRecordResultState.stop;
private float disTime = 0;
private int startsimple = 0;
private float noAudiodisTime = 0;
void Start()
{
micArray = Microphone.devices;
// Type[] allType = GetHotfixTypes();// BlockBaseDataTypeList = allType.Where(type => !type.IsAbstract).Where(type => typeof(MonoBehaviour) == type.BaseType).ToList();
// Debug.LogError(allType.Length+" "+BlockBaseDataTypeList.Count);
Play();
}
public void Play()
{
Debug.LogError("@@@@@@");
if (micArray.Length == 0)
{
Debug.Log("No Record Device!");
return;
}
noAudiodisTime = Time.time + ClearAudioTime;
CurrentHaveRecordRealAudio = false;
if (recordedClip != null)
{
Microphone.End(null);
DestroyImmediate(recordedClip);
recordedClip = null;
}recordedClip = Microphone.Start(null, false, RECORD_TIME, 16000 ); //44100
float a = Microphone.GetPosition(null);
while (!(Microphone.GetPosition(null) > 0))
{
}currentTyp = AudioRecordResultState.start;
Debug.Log("StartRecord");
}public void Stop() {
currentTyp = AudioRecordResultState.stop;
}public Type[] GetHotfixTypes()
{
foreach(var a in AppDomain.CurrentDomain.GetAssemblies())
{
Debug.LogError(a.FullName);
}
return null;}
void Update()
{
if (currentTyp == AudioRecordResultState.start)
{
float value = GetLevelMax();
// Debug.LogError(value);
if (value >= limateAudioLevel)
{
disTime = Time.time + 2;if (!CurrentHaveRecordRealAudio)
{
Debug.LogError("!!!!!!!!!!!!!!$$$ "+ value);
startsimple = Microphone.GetPosition(null)-1;
startsimple = Mathf.Max(0, startsimple);
CurrentHaveRecordRealAudio = true;
}
}
if (CurrentHaveRecordRealAudio)
{
if (value < limateAudioLevel && Time.time>= disTime) {
Debug.LogError("!!!!!!!!!!!!!!!!!!!!11111122222");
//todo sendAudio
SendAudio();
}
}
else
{
if (recordedClip != null&& Time.time>= noAudiodisTime) {
Debug.LogError(recordedClip.length+"!!!!!!!!!!!!!!!^^ "+ ClearAudioTime);
Play();
}
}
}
}public void SendAudio() {
CurrentHaveRecordRealAudio = false;
disTime = Time.time + 2;
int endPoint = Microphone.GetPosition(null);
var samples = new float[endPoint- startsimple];recordedClip.GetData(samples, startsimple);
var newrecordedClip = AudioClip.Create(recordedClip.name,
(endPoint - startsimple),
recordedClip.channels,
recordedClip.frequency,
false);newrecordedClip.SetData(samples, 0);
string file;
var data = WavUtility.FromAudioClip(newrecordedClip, out file, true);
Destroy(newrecordedClip);
}
///
/// 获取麦克风音量
///
///
public float GetLevelMax()
{
float levelMax = 0;
float[] waveData = new float[_sampleWindow];
int micPosition = Microphone.GetPosition(null) - (_sampleWindow + 1); // null means the first microphone
if (micPosition < 0) return 0;
recordedClip.GetData(waveData, micPosition);// Getting a peak on the last 128 samples
for (int i = 0; i < _sampleWindow; i++)
{
float wavePeak = waveData[i] * waveData[i];
if (levelMax < wavePeak)
{
levelMax = wavePeak;
}
}
return levelMax;
}}
}
百度语音上传的注意事项:
麦克风需要16K录制 即 16000 ;而不是通常的44100;否则报音频质量差的问题