首页 > 编程语言 > 详细

Unity Microphone 无限时长录制

时间:2019-01-03 18:55:25      阅读:384      评论:0      收藏:0      [点我收藏+]

 

原创文章:转载请标明出处--博客园 Jason_c

 

Unity可以很方便的通过 Microphone.Start()方法来调用麦克风,但是有一个弊端是,必须传入时长,这就很尴尬了,因为大多数时间,我们是不知道用户需要何时关闭麦克风的,

这里提供一个解决思路:

1、将microphone设置为循环录制,即:

Microphone.Start(micName, true,2,16000);  

  

2、每隔一定间隔读取录制好的数据,并将它缓存起来。

这里值得一提的是,如果每隔2秒保存一下音频数据(因为我设置的录制时间是2秒),

因为代码运行也需要时间,会导致音频数据损坏,声音会出现明显的断层现象,所以这里将它分段保存就能解决这种问题,

当麦克风录制的位置大于音频的一半的时候,保存上一段音频,当麦克风录制完时,保存后一段音频。

 

     bool isSaveFirstHalf = true;//将音频从中间分生两段,然后分段保存
        int micPosition;
        while (!isMicRecordFinished)
        {
            if (isSaveFirstHalf)
            {
                yield return new WaitUntil(() => { micPosition = Microphone.GetPosition(micName);return micPosition > length * 6 / 10 && micPosition < length; });//保存前半段
                micDataTemp = new float[length / 2];
                micClip.GetData(micDataTemp, 0);
                micDataList.AddRange(micDataTemp);
                isSaveFirstHalf = !isSaveFirstHalf;
            }
            else
            {
                yield return new WaitUntil(() => { micPosition = Microphone.GetPosition(micName); return micPosition > length / 10 && micPosition < length / 2; });//保存后半段
                micDataTemp = new float[length/2];
                micClip.GetData(micDataTemp, length / 2);
                micDataList.AddRange(micDataTemp);
                isSaveFirstHalf = !isSaveFirstHalf;
            }

        }

最后处理一下结束时的音频

     micPosition = Microphone.GetPosition(micName);
        if (micPosition <= length)//前半段
        {
            micDataTemp = new float[micPosition/2];
            micClip.GetData(micDataTemp, 0);
        }
        else
        {
            micDataTemp = new float[micPosition - length/2];
            micClip.GetData(micDataTemp, length/2);
        }

  

3、最后通过保存的数据生成新的音频,即:

AudioClip.Create("RecordClip", micDataList.Count, 1, 16000, false);

newAudioClip.SetData(micDataList.ToArray(), 0);

 

 

完整代码如下:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MicUnlimitedDuration : MonoBehaviour {
    public delegate void AudioRecordHandle(AudioClip audioClip);
    public AudioSource audioSource;

    AudioClip micClip;


    bool isMicRecordFinished= true;

    List<float> micDataList = new List<float>();
    float[] micDataTemp;

    string micName;

    public void StartMicrophone() {
        StopCoroutine(StartMicrophone(null, PlayAudioRecord));
        StartCoroutine(StartMicrophone(null, PlayAudioRecord));
    }


    IEnumerator StartMicrophone(string microphoneName,AudioRecordHandle  audioRecordFinishedEvent) {
        Debug.Log("Start Mic");
        micDataList = new List<float>();
        micName = microphoneName;
        micClip = Microphone.Start(micName, true,2,16000);
        isMicRecordFinished = false;
        int length = micClip.channels * micClip.samples;
        bool isSaveFirstHalf = true;//将音频从中间分生两段,然后分段保存
        int micPosition;
        while (!isMicRecordFinished)
        {
            if (isSaveFirstHalf)
            {
                yield return new WaitUntil(() => { micPosition = Microphone.GetPosition(micName);return micPosition > length * 6 / 10 && micPosition < length; });//保存前半段
                micDataTemp = new float[length / 2];
                micClip.GetData(micDataTemp, 0);
                micDataList.AddRange(micDataTemp);
                isSaveFirstHalf = !isSaveFirstHalf;
            }
            else
            {
                yield return new WaitUntil(() => { micPosition = Microphone.GetPosition(micName); return micPosition > length / 10 && micPosition < length / 2; });//保存后半段
                micDataTemp = new float[length/2];
                micClip.GetData(micDataTemp, length / 2);
                micDataList.AddRange(micDataTemp);
                isSaveFirstHalf = !isSaveFirstHalf;
            }

        }
        micPosition = Microphone.GetPosition(micName);
        if (micPosition <= length)//前半段
        {
            micDataTemp = new float[micPosition/2];
            micClip.GetData(micDataTemp, 0);
        }
        else
        {
            micDataTemp = new float[micPosition - length/2];
            micClip.GetData(micDataTemp, length/2);
        }
        micDataList.AddRange(micDataTemp);
        Microphone.End(micName);
        AudioClip newAudioClip = AudioClip.Create("RecordClip", micDataList.Count, 1, 16000, false);
        newAudioClip.SetData(micDataList.ToArray(), 0);
        audioRecordFinishedEvent(newAudioClip);
        Debug.Log("RecordEnd");
    }



    public void StopMicrophone()
    {
        Debug.Log("Stop mic");
        isMicRecordFinished = true;
    }

    void PlayAudioRecord(AudioClip newAudioClip)
    {
        audioSource.clip = newAudioClip;
        audioSource.Play();
    }
}

 

如果这篇文章对您有所帮助,打赏一下作者吧,码字也挺辛苦的

 

技术分享图片                               技术分享图片

Unity Microphone 无限时长录制

原文:https://www.cnblogs.com/Jason-c/p/10216075.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!