Unity中使用Microphone录音保存以及回放

录音类

MicrophoneManager包含开始录音,停止录音,播放录音以及录音的保存等。

public partial class MicrophoneManager : MonoBehaviour
{
    private static MicrophoneManager m_instance;

    private static string[] micArray = null; //录音设备列表
    private AudioClip audioClip;
    private DateTime beginTime;

    public float sensitivity=100;
    public float loudness=0; 

    const int HEADER_SIZE = 44;
    const int RECORD_TIME = 10;
    const int RECORD_RATE = 44100; //录音采样率

    //void Awake()
    //{
    //    m_instance = this;
    //}
    public static MicrophoneManager GetInstance()
    {
        if (m_instance == null)
        {
            micArray = Microphone.devices;
            if (micArray.Length == 0)
            {
                Debug.LogError("no mic device");
            }
            foreach (string deviceStr in Microphone.devices)
            {
                Debug.Log("device name = " + deviceStr);
            }
            GameObject micManager=new GameObject("MicManager");
            m_instance= micManager.AddComponent<MicrophoneManager>();
        }
        return m_instance;
    }  

    /// <summary>
    /// 开始录音
    /// </summary>
    public void StartRecord()
    {
        if (micArray.Length == 0)
        {
            Debug.Log("No Record Device!");
            return;
        }
        Microphone.End(null);//录音时先停掉录音,录音参数为null时采用默认的录音驱动
        beginTime = DateTime.Now;
        audioClip = Microphone.Start(null, false, RECORD_TIME, RECORD_RATE);
        while (!(Microphone.GetPosition(null)>0)) {
        }
        Debug.Log("StartRecord");
    }  

    /// <summary>
    /// 停止录音
    /// </summary>
    public void StopRecord()
    {
        if (micArray.Length == 0)
        {
            Debug.Log("No Record Device!");
            return;
        }
        if (!Microphone.IsRecording(null))
        {
            return;
        }
        Microphone.End (null);
        Debug.Log("StopRecord");
    }

    /// <summary>
    ///播放录音
    /// </summary>
    public void PlayRecord()
    {
        PlayRecord(audioClip);
    }
    public void PlayRecord(AudioClip clip)
    {
        PlayRecord(clip,Vector3.zero);
    }

    public void PlayRecord(AudioClip clip, Vector3 pos)
    {
        if (clip == null)
        {
            Debug.Log("audioClip is null");
            return;
        }
        AudioSource.PlayClipAtPoint(clip, pos);
        Debug.Log("PlayRecord");
    }

    public byte[] Save()
    {
        if (audioClip == null) return null;
        return WavUtility.FromAudioClip(audioClip);
    }

    public void Save(string path,string filename)
    {
        Save(audioClip,path,filename);
    }

    public void Save(AudioClip clip, string path, string filename)
    {
        if (clip == null)
        {
            Debug.Log("clip is null,can‘t be saved");
            return;
        }
        WavUtility.FromAudioClip(clip, path, filename, true);
    }

    public AudioClip Read(string path)
    {
       return WavUtility.ToAudioClip(path);
    }

    public AudioClip Read(byte[] data)
    {
       return WavUtility.ToAudioClip(data);
    }

    public JObject SaveAudioClip()
    {
        JObject jd = new JObject();
        jd["time"] = beginTime.ToString("yyMMdd-HHmmss-fff");
        //jd["time"] = beginTime.ToFileTime();
        //使用Unicode编码,其他编码格式会有问题
        jd["audioclip"] = Encoding.Unicode.GetString(Save());
        return jd;
    }
}

录音的保存

WavUtility是对录音数据的保存和读取,可以保存为本地文件.wav或者byte数组进行传输。这个东东是我从github上发现的,由于代码太长就不贴了,网址放上:https://github.com/deadlyfingers/UnityWav

重要的方法

/// - Use "ToAudioClip" method for loading wav file / bytes.
/// Loads .wav (PCM uncompressed) files at 8,16,24 and 32 bits and converts data to Unity‘s AudioClip.
/// - Use "FromAudioClip" method for saving wav file / bytes.
/// Converts an AudioClip‘s float data into wav byte array at 16 bit.

public static AudioClip ToAudioClip (string filePath)

public static AudioClip ToAudioClip (byte[] fileBytes, int offsetSamples = 0, string name = "wav")

public static byte[] FromAudioClip (AudioClip audioClip)

public static byte[] FromAudioClip (AudioClip audioClip,string filepath,string filename, bool saveAsFile = true)

录音的回放

为了方便回放,又不额外引入其他文件来记录回放时间与录音的对应信息,将录音时间作为文件名(ex:170515-114114-676),并在开始的时候录一个空录音作为起始时间,回放代码如下:

 IEnumerator PlayAudioClip()
    {
        string[] files = Directory.GetFiles(savePath);
        if (files.Length > 0)
        {
            List<string> temp = new List<string>();
            for (int i = 0; i < files.Length; i++)
            {
                if (!files[i].Contains(".meta"))
                    temp.Add(files[i]);
            }
            string[] audioFiles = temp.ToArray();
            Array.Sort(audioFiles);
            float interval = 0f;
            for (int i = 0; i < audioFiles.Length - 1; i++)
            {
                AudioClip clip = MicrophoneManager.GetInstance().Read(audioFiles[i]);
                MicrophoneManager.GetInstance().PlayRecord(clip);
                interval = (float)(GetTime(audioFiles[i + 1]) - GetTime(audioFiles[i])).TotalSeconds;
                Debug.Log(interval);
                yield return new WaitForSeconds(interval);
            }
            MicrophoneManager.GetInstance().PlayRecord
            (
               MicrophoneManager.GetInstance().Read(audioFiles[audioFiles.Length - 1])
            );
        }
    }
时间: 2024-11-03 22:33:30

Unity中使用Microphone录音保存以及回放的相关文章

【原创】在Unity中关于多态转换与序列化保存的细节

在Unity中关于多态转换与序列化保存的细节 环境: 在unity中为类变量分类. [System.Serializable] public class dllProperty { public int num1 = 1; public string name1 = "dll"; public bool isOn = false; } [System.Serializable] public class myProperty : dllProperty { public int num

菜鸟学习 - Unity中的热更新 - Lua和C#通信

孙广东 2015-4-6 热更新我是个菜鸟,感谢网上的各位的奉献,这次又当一回搬运工. 准备: 1.了解Lua的语法 推荐书籍<Lua程序设计 第二版> 2.使用ULua插件进行通信 尽量早上真机.因为Bug问题特别多. 大杂烩: 更新LUa其实也是更新资源. Lua被看作一个资源么.Lua代码都是运行时才编译的,不运行的时候就如同一张图片.一段音频一样,都是文件资源:所以更新逻辑只需要更新脚本,不需要再编译,因而Lua能轻松实现"热更新".运行效率由于使用反射,所以成为它

Spine工具在Unity中的使用

Spine工具以前都是跟Cocos 2d结合的比较多,很多人以为Unity有了Toolkit 2d和NGUI不需要Spine了,其实这种理解是错误的,Spine非常适合Unity,不需要Toolkit 2D,自己本身就可以适应Unity. 而且由于他的资源量非常少,在效率和安装包方面都比Toolkit 2D好一些,现在Spine工具已经开始在Unity中使用了. Spine说白了它就是一种调试2D骨骼动画的工具,经过它调试的工具如何在Unity中使用?我们下面开始围绕这个问题展开讨论. 首先我们

【《Effective C#》提炼总结】提高Unity中C#代码质量的22条准则

本文由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/53869998 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 引言 我们知道,在C++领域,作为进阶阅读材料,必看的书是<Effective C++>. 而<Effective C#>之于C# ,是类似<Effective C++>之于C++一样的存在. 这篇文章,

Unity中2D和UGUI图集的理解与使用

图集 什么是图集? 在使用3D技术开发2D游戏或制作UI时(即使用GPU绘制),都会使用到图集,而使用CPU渲染的2D游戏和UI则不存在图集这个概念(比如Flash的原生显示列表),那么什么是图集呢?准确的说法图集是一张包含了多个小图的大图和一份记录了每个小图id.位置.尺寸等数据的数据文件,一个图集应该对应两个文件,当然也有人把数据集成到图片中,导致看起来只有一张图片(参考自DragonBones的做法). 为什么要用图集? 在GPU已经成为PC.手机等设备的必备组件的现在,把所有显示的绘制操

在 Unity 中使用 Android SDK

如果你想知道什么是爱.我们从哪里来.生命的意义.宇宙的起源,那么请不要看这篇文章. 这只是一篇无聊的文章,除非你是一只正在被折磨的猿猴,否则请跳过. 将 Java 代码做成 Unity 插件 下载 Android sdk.在 Unity 中配置好路径,保证 Unity 可以正常导出 apk:下载 JDK .配置好环境变量,保证 Eclipse 可以正常打开.另外你需要知道使用Eclipse的logcat查看调试log. 1.打开 Eclipse,建立一个 Android 空项目,注意 packa

手机浏览器,微信中播放amr录音

由于微信公众号开发中,临时素材只有三天的有效期,但是客户要求所有录音永久保存,永久素材数量又有限制,故只能把录音保存到服务器上.但是存到服务器上有一个问题,手机微信中无法直接播放amr录音.无意中发现此js文件,完美解决微信中播放amr的问题.特此记录. demo地址: 链接: http://pan.baidu.com/s/1dE4fmzJ 密码: pdru

关于Unity中的光照(四)

渲染路径和颜色空间 1:Unity光影效果可以通过设置 渲染路径和颜色空间;2: 渲染路径: 光照到物体表面,物体着色的时候,算上光的颜色的时候有这么几种光照的着色方式,计算着色的方式 forward: 着色时根据对应影响的灯光,每个光源着色一次,多个光源作用时会着色多次; 优点: 快速,硬件要求低,快速的处理透明; 缺点: 每个光源都要有对应的成本,大量光源反而降低; Deferred: 延迟渲染路径,将光的颜色着色到几何缓冲器,生成一个屏幕空间的贴图,大量realttime光源模式的时候更真

unity中射线碰撞检测总结

这阵子通过看视频,看书对unity中射线碰撞检测,有了一些了解,这里我把它总结一下写下来,希望能帮助到你们,也希望通过各位大神来指正不足之处: 射线碰撞检测,就是由某一物体发射出一道射线,射线碰撞到物体之后,可以得到该物体的相关信息,然后就可以对该物体进行一些操作的过程了.PS:个人见解: 射线的发射分为可见和不可见,可见的情况就是在游戏当中你可以看到射线,而不可见就是游戏运行时,你只可以在Scene试图下观察到它,而这到射线又是存在的: 而其实两者区别不大,关键是看你怎么用它了: 下面先看看不