最近项目要用到Unity录音功能,便在网上搜索了一下,Unity提供的有一个录音相关的类Microphone
文章内容是四处找的加个自己的修改,基本上不用改代码可以直接用,存做学习用,并方便新手看,如涉嫌侵权,请及时告知,以便删除。
主要用到的函数有:
Microphone.devices
Microphone.Start
Microphone.End
下面上代码
private string path;
private AudioSource aud;
public int recordMaxTime = 10; //录音的最大时长(秒) [Range(8000, 44100)]
public int frequency = 8000; //录音的采样率
private string[] micDevices; //录音设备
void Start()
{
path = SaveWav.path;
aud = GetComponent<AudioSource>();
micDevices = Microphone.devices;
foreach (string device in micDevices)
{
Debug.Log("MicrophoneName: " + device); //win7默认录音设备名称为空
Directory.CreateDirectory(path);
}
}
/// <summary>
/// 开始录音
/// /// </summary>
public void StartRecord()
{
if (micDevices.Length == 0)
{ Debug.Log("没有麦克风驱动!!");
return; //如果没有录音设备不处理
}
Debug.Log("start");
Microphone.End(null);
//开始录音之前先确保结束上次录音
aud.clip = Microphone.Start(null, false, recordMaxTime, frequency); //开始录音
}
private int index = 0;
private int audioLength;//录音的长度
/// <summary>
/// 结束录音
/// </summary>
public void EndRecord()
{
int lastPos = Microphone.GetPosition(null);
if (Microphone.IsRecording(null))
audioLength = lastPos / frequency;//录音时长
else
audioLength = 10;
Debug.Log("stop");
Microphone.End(null); //
if (audioLength < 1f) //
return;//录音小于1秒不处理
index++;
cSaveRecord(); //保存
}
/// <summary>
/// 保存录音
/// /// </summary>
public void SaveRecord()
{
if (CheckFile("Record" + index.ToString()) == true) //如果此文件已存在
{ index += 1; //索引+1
SaveRecord(); //递归再次检查是否存在
}
SaveWav.Save("Record" + index.ToString(), aud.clip); //保存
Debug.Log("录音时长为:" + audioLength + "秒!");
}
/// <summary>
/// 检查是否已存在此名称
/// </summary>
/// <param name="fileName">文件名</param>
/// <returns>是否存在</returns>
private bool CheckFile(string fileName)
{
var filePath = Path.Combine(path, fileName + ".wav");
if (File.Exists(filePath))
return true; //如果文件夹存在此文件名,返回True
else
return false; //否则返回False
}
/// <summary>
/// 读取音频文件
/// </summary>
/// <param name="recordPath">路径</param>
/// <returns></returns>
public IEnumerator LoadAudio(string recordPath)
{
WWW www = new WWW(@"file:///" + recordPath + ".wav");
yield return www;
var clipTemp = www.audioClip;
aud.clip = clipTemp; aud.Play();
}
/// <summary>
/// 播放录音
/// </summary>
public void PlayRecord()
{
EndRecord();
AudioSource.PlayClipAtPoint(aud.clip, Vector3.zero);
}
保存音频的类
/// <summary>
/// 保存为Wav文件
/// </summary>
public static class SaveWav
{
const int HEADER_SIZE = 44;
public static string path = "D:/SHWT_VR/SHWTRecord";
/// <summary>
/// 保存 /// </summary>
/// <param name="filename">文件名称</param>
/// <param name="clip">录音片段</param>
/// <returns></returns>
public static bool Save(string filename, AudioClip clip)
{
if (!filename.ToLower().EndsWith(".wav"))
{
filename += ".wav";
}
var filepath = Path.Combine(path, filename);
Debug.Log(filepath);
Directory.CreateDirectory(Path.GetDirectoryName(filepath));//创建一个路径文件夹
using (var fileStream = CreateEmpty(filepath))
{
ConvertAndWrite(fileStream, clip);
WriteHeader(fileStream, clip);
}
return true;
}
static void ConvertAndWrite(FileStream fileStream, AudioClip clip)
{
var samples = new float[clip.samples];
clip.GetData(samples, 0);
Int16[] intData = new Int16[samples.Length];
//converting in 2 float[] steps to Int16[], //then Int16[] to Byte[]
Byte[] bytesData = new Byte[samples.Length * 2];
//bytesData array is twice the size of //dataSource array because a float converted in Int16 is 2 bytes.
int rescaleFactor = 32767;//to convert float to Int16
for (int i = 0; i < samples.Length; i++)
{
intData[i] = (short)(samples[i] * rescaleFactor);
Byte[] byteArr = new Byte[2];
byteArr = BitConverter.GetBytes(intData[i]);
byteArr.CopyTo(bytesData, i * 2);
}
fileStream.Write(bytesData, 0, bytesData.Length);
}
private static FileStream CreateEmpty(string filepath)
{
FileStream fileStream = new FileStream(filepath, FileMode.Create);
byte emptyByte = new byte();
for (int i = 0; i < 44; i++)
{
fileStream.WriteByte(emptyByte);
}
return fileStream;
}
static void WriteHeader(FileStream fileStream, AudioClip clip)
{
var hz = clip.frequency;
var channels = clip.channels;
var samples = clip.samples;
fileStream.Seek(0, SeekOrigin.Begin);
Byte[] riff = System.Text.Encoding.UTF8.GetBytes("RIFF");
fileStream.Write(riff, 0, 4);
Byte[] chunkSize = BitConverter.GetBytes(fileStream.Length - 8);
fileStream.Write(chunkSize, 0, 4);
Byte[] wave = System.Text.Encoding.UTF8.GetBytes("WAVE");
fileStream.Write(wave, 0, 4);
Byte[] fmt = System.Text.Encoding.UTF8.GetBytes("fmt ");
fileStream.Write(fmt, 0, 4);
Byte[] subChunk1 = BitConverter.GetBytes(16);
fileStream.Write(subChunk1, 0, 4);
UInt16 two = 2;
UInt16 one = 1;
Byte[] audioFormat = BitConverter.GetBytes(one);
fileStream.Write(audioFormat, 0, 2);
Byte[] numChannels = BitConverter.GetBytes(channels);
fileStream.Write(numChannels, 0, 2);
Byte[] sampleRate = BitConverter.GetBytes(hz);
fileStream.Write(sampleRate, 0, 4);
Byte[] byteRate = BitConverter.GetBytes(hz * channels * 2);
// sampleRate * bytesPerSample*number of channels, here 44100*2*2
fileStream.Write(byteRate, 0, 4);
UInt16 blockAlign = (ushort)(channels * 2);
fileStream.Write(BitConverter.GetBytes(blockAlign), 0, 2);
UInt16 bps = 16; Byte[] bitsPerSample = BitConverter.GetBytes(bps);
fileStream.Write(bitsPerSample, 0, 2);
Byte[] datastring = System.Text.Encoding.UTF8.GetBytes("data");
fileStream.Write(datastring, 0, 4);
Byte[] subChunk2 = BitConverter.GetBytes(samples * channels * 2);
fileStream.Write(subChunk2, 0, 4); //
fileStream.Close();
}
备注:这个录制只能录制麦克风传进去的声音,背景音乐一起录制还没有实现,如果有大神,欢迎指导。

浙公网安备 33010602011771号