Introduction
I was building a voice recording feature using a smartphone microphone in Unity. The requirement was simple: tap a button to start recording, tap again to stop. However, I ran into a problem — I couldn't get the accurate recording duration. This article explains how I solved it.
Unity's Microphone Class
Unity provides a built-in Microphone class for recording audio.
Unity Documentation | Microphone
On iPhone, Android, and Mac, it uses the built-in microphone. On Windows, Unity will detect any connected microphone automatically (probably).
Sample Code (Updated: 2018/10/21)
I created a sample Unity project. Feel free to use it.
https://github.com/segurvita/UnityMicrophonePractice
It supports starting/stopping recording and playback via button controls.
Code Walkthrough
Here is the full sample code:
using UnityEngine;
public class RecordManager : MonoBehaviour
{
// Public variables
public int maxDuration; // Maximum recording duration (e.g., 20 seconds)
public AudioClip audioClip; // Audio data
// Private variables
private const int sampleRate = 16000; // Recording sample rate
private string mic; // Microphone device name
///-----------------------------------------------------------
/// <summary>Start recording</summary>
///-----------------------------------------------------------
public void StartRecord()
{
// Check if microphone exists
if (Microphone.devices.Length == 0)
{
Debug.Log("No microphone found");
return;
}
// Get microphone name
mic = Microphone.devices[0];
// Start recording; store audio data in audioClip
audioClip = Microphone.Start(mic, false, maxDuration, sampleRate);
}
///-----------------------------------------------------------
/// <summary>Stop recording</summary>
///-----------------------------------------------------------
public void StopRecord()
{
// Get the current recording position
int position = Microphone.GetPosition(mic);
// Force stop the microphone
Microphone.End(mic);
// Checking the duration shows maxDuration regardless of when we stopped — does it include silence?
Debug.Log("Recording duration before fix: " + audioClip.length);
// Allocate a temporary buffer and copy all audio data from audioClip
float[] soundData = new float[audioClip.samples * audioClip.channels];
audioClip.GetData(soundData, 0);
// Create a new buffer sized exactly to the recorded position
float[] newData = new float[position * audioClip.channels];
// Copy only the recorded portion
for (int i = 0; i < newData.Length; i++)
{
newData[i] = soundData[i];
}
// Create a new AudioClip instance and set the trimmed audio data
AudioClip newClip = AudioClip.Create(audioClip.name, position, audioClip.channels, audioClip.frequency, false);
newClip.SetData(newData, 0);
// Replace the original audioClip with the new one
AudioClip.Destroy(audioClip);
audioClip = newClip;
// Log the corrected duration
Debug.Log("Recording duration after fix: " + newClip.length);
}
}
Explaining StartRecord
Starting the recording is straightforward — just call:
audioClip = Microphone.Start(mic, false, maxDuration, sampleRate);
Without explicitly stopping, it will record for maxDuration seconds. The audio data is stored in audioClip, which is an instance of the AudioClip class — Unity's container for audio data. To play it back, pass audioClip to an AudioSource and call Play().
Explaining StopRecord
Stopping mid-recording is where things get complicated.
Calling:
Microphone.End(mic);
stops the recording, but leaves audioClip in an unexpected state. Even if you stopped after 3 seconds, audioClip.length reports the full maxDuration — for example, 20 seconds.
It turns out audioClip.length is fixed to maxDuration the moment Microphone.Start() is called.
Since audioClip.length is read-only, I worked around this by reconstructing the AudioClip instance. I referenced this Q&A for the approach:
record dynamic length from microphone
If there's a cleaner way, I'd love to hear it.
Also, note this line:
int position = Microphone.GetPosition(mic);
This must be called before Microphone.End(mic). If called after, position will be 0.
Summary
Unity's Microphone class makes it easy to record audio, but getting an accurate recording duration requires some extra work — specifically, reconstructing the AudioClip with the correct length after stopping.
Top comments (0)