Unity录音保存方法

发表于2017-08-24
评论0 2.7k浏览
  想在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);
 
        }

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

0个评论