Unity录音保存方法
发表于2017-08-24
想在Unity中对录音进行保存,就必须要借助Unity中自带的Microphone类来实现,可能有些开发者对这个Microphone类还不是很熟悉,下面就给大家介绍下使用Microphone类实现录音保存的方法,一起来看看吧。
Tips:在保存录音时需要注意音频格式,Unity录音默认是wav格式。
下面是代码实现:
开始录音
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | private AudioClip clip; //录音的采样率 const int samplingRate = 44100; private TimerInfo timerInfo; ///
/// 开始录音 /// public void Recording() { string [] micDevices = Microphone.devices; if (micDevices.Length == 0) { Util.Log( "没有找到录音组件" ); UpdateMessage( "没有找到录音组件" ); return ; } Util.Log( "录音时长为30秒" ); UpdateMessage( "录音时长为30秒" ); Microphone.End( null ); //录音前先停掉录音,录音参数为null时采用的是默认的录音驱动 clip = Microphone.Start( null , false , 30, samplingRate); timerInfo = new TimerInfo( this ); //时间管理 TimerManager.AddTimerEvent(timerInfo); //添加到时间管理器中 } ///
/// 停止录音 /// public void StopRecord() { TimerManager.StopTimerEvent(timerInfo); TimerManager.RemoveTimerEvent(timerInfo); index = 0; int audioLength; int lastPos = Microphone.GetPosition( null ); if (Microphone.IsRecording( null )) { audioLength = lastPos / samplingRate; } else { audioLength = 30; } Microphone.End( null ); if (audioLength < 1.0f) { Util.Log( "录音时长短" ); UpdateMessage( "录音时长短" ); } } ///
/// 播放录音 /// public void PlayRecord() { StopRecord(); AudioSource.PlayClipAtPoint(clip, Vector3.zero); } ///
/// 保存录音 /// public void SaveRecord() { try { Util.Save(clip, Util.DataPath "testmodel/testproject/other/record.wav" ); Util.Log( "保存完毕" ); UpdateMessage( "保存完毕" ); } catch (Exception ex) { Util.Log(ex.Message ex.StackTrace); UpdateMessage(ex.Message ex.StackTrace); } } public static void Save(AudioClip clip, string path) { string filePath = Path.GetDirectoryName(path); if (!Directory.Exists(filePath)) { Directory.CreateDirectory(filePath); } using (FileStream fileStream = CreateEmpty(path)) { ConvertAndWrite(fileStream, clip); WriteHeader(fileStream, clip); } } private static void ConvertAndWrite(FileStream fileStream, AudioClip clip) { float [] samples = new float [clip.samples]; clip.GetData(samples, 0); Int16[] intData = new Int16[samples.Length]; Byte[] bytesData = new Byte[samples.Length * 2]; 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 ) //preparing the header { fileStream.WriteByte(emptyByte); } return fileStream; } private static void WriteHeader(FileStream stream, AudioClip clip) { int hz = clip.frequency; int channels = clip.channels; int samples = clip.samples; stream.Seek(0, SeekOrigin.Begin); Byte[] riff = System.Text.Encoding.UTF8.GetBytes( "RIFF" ); stream.Write(riff, 0, 4); Byte[] chunkSize = BitConverter.GetBytes(stream.Length - 8); stream.Write(chunkSize, 0, 4); Byte[] wave = System.Text.Encoding.UTF8.GetBytes( "WAVE" ); stream.Write(wave, 0, 4); Byte[] fmt = System.Text.Encoding.UTF8.GetBytes( "fmt " ); stream.Write(fmt, 0, 4); Byte[] subChunk1 = BitConverter.GetBytes(16); stream.Write(subChunk1, 0, 4); UInt16 two = 2; UInt16 one = 1; Byte[] audioFormat = BitConverter.GetBytes(one); stream.Write(audioFormat, 0, 2); Byte[] numChannels = BitConverter.GetBytes(channels); stream.Write(numChannels, 0, 2); Byte[] sampleRate = BitConverter.GetBytes(hz); stream.Write(sampleRate, 0, 4); Byte[] byteRate = BitConverter.GetBytes(hz * channels * 2); // sampleRate * bytesPerSample*number of channels, here 44100*2*2 stream.Write(byteRate, 0, 4); UInt16 blockAlign = ( ushort )(channels * 2); stream.Write(BitConverter.GetBytes(blockAlign), 0, 2); UInt16 bps = 16; Byte[] bitsPerSample = BitConverter.GetBytes(bps); stream.Write(bitsPerSample, 0, 2); Byte[] datastring = System.Text.Encoding.UTF8.GetBytes( "data" ); stream.Write(datastring, 0, 4); Byte[] subChunk2 = BitConverter.GetBytes(samples * channels * 2); stream.Write(subChunk2, 0, 4); } |