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

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

这里提供一个解决思路:

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

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

  

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

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

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

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

  1.     bool isSaveFirstHalf = true;//将音频从中间分生两段,然后分段保存
  2. int micPosition;
  3. while (!isMicRecordFinished)
  4. {
  5. if (isSaveFirstHalf)
  6. {
  7. yield return new WaitUntil(() => { micPosition = Microphone.GetPosition(micName);return micPosition > length * 6 / 10 && micPosition < length; });//保存前半段
  8. micDataTemp = new float[length / 2];
  9. micClip.GetData(micDataTemp, 0);
  10. micDataList.AddRange(micDataTemp);
  11. isSaveFirstHalf = !isSaveFirstHalf;
  12. }
  13. else
  14. {
  15. yield return new WaitUntil(() => { micPosition = Microphone.GetPosition(micName); return micPosition > length / 10 && micPosition < length / 2; });//保存后半段
  16. micDataTemp = new float[length/2];
  17. micClip.GetData(micDataTemp, length / 2);
  18. micDataList.AddRange(micDataTemp);
  19. isSaveFirstHalf = !isSaveFirstHalf;
  20. }
  21.  
  22. }

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

  1.     micPosition = Microphone.GetPosition(micName);
  2. if (micPosition <= length)//前半段
  3. {
  4. micDataTemp = new float[micPosition/2];
  5. micClip.GetData(micDataTemp, 0);
  6. }
  7. else
  8. {
  9. micDataTemp = new float[micPosition - length/2];
  10. micClip.GetData(micDataTemp, length/2);
  11. }

  

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

  1. AudioClip.Create("RecordClip", micDataList.Count, 1, 16000, false);
  2.  
  3. newAudioClip.SetData(micDataList.ToArray(), 0);

完整代码如下:

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5.  
  6. public class MicUnlimitedDuration : MonoBehaviour {
  7. public delegate void AudioRecordHandle(AudioClip audioClip);
  8. public AudioSource audioSource;
  9.  
  10. AudioClip micClip;
  11.  
  12. bool isMicRecordFinished= true;
  13.  
  14. List<float> micDataList = new List<float>();
  15. float[] micDataTemp;
  16.  
  17. string micName;
  18.  
  19. public void StartMicrophone() {
  20. StopCoroutine(StartMicrophone(null, PlayAudioRecord));
  21. StartCoroutine(StartMicrophone(null, PlayAudioRecord));
  22. }
  23.  
  24. IEnumerator StartMicrophone(string microphoneName,AudioRecordHandle audioRecordFinishedEvent) {
  25. Debug.Log("Start Mic");
  26. micDataList = new List<float>();
  27. micName = microphoneName;
  28. micClip = Microphone.Start(micName, true,,);
  29. isMicRecordFinished = false;
  30. int length = micClip.channels * micClip.samples;
  31. bool isSaveFirstHalf = true;//将音频从中间分生两段,然后分段保存
  32. int micPosition;
  33. while (!isMicRecordFinished)
  34. {
  35. if (isSaveFirstHalf)
  36. {
  37. yield return new WaitUntil(() => { micPosition = Microphone.GetPosition(micName);return micPosition > length * / && micPosition < length; });//保存前半段
  38. micDataTemp = new float[length / ];
  39. micClip.GetData(micDataTemp, );
  40. micDataList.AddRange(micDataTemp);
  41. isSaveFirstHalf = !isSaveFirstHalf;
  42. }
  43. else
  44. {
  45. yield return new WaitUntil(() => { micPosition = Microphone.GetPosition(micName); return micPosition > length / && micPosition < length / ; });//保存后半段
  46. micDataTemp = new float[length/];
  47. micClip.GetData(micDataTemp, length / );
  48. micDataList.AddRange(micDataTemp);
  49. isSaveFirstHalf = !isSaveFirstHalf;
  50. }
  51.  
  52. }
  53. micPosition = Microphone.GetPosition(micName);
  54. if (micPosition <= length)//前半段
  55. {
  56. micDataTemp = new float[micPosition/];
  57. micClip.GetData(micDataTemp, );
  58. }
  59. else
  60. {
  61. micDataTemp = new float[micPosition - length/];
  62. micClip.GetData(micDataTemp, length/);
  63. }
  64. micDataList.AddRange(micDataTemp);
  65. Microphone.End(micName);
  66. AudioClip newAudioClip = AudioClip.Create("RecordClip", micDataList.Count, , , false);
  67. newAudioClip.SetData(micDataList.ToArray(), );
  68. audioRecordFinishedEvent(newAudioClip);
  69. Debug.Log("RecordEnd");
  70. }
  71.  
  72. public void StopMicrophone()
  73. {
  74. Debug.Log("Stop mic");
  75. isMicRecordFinished = true;
  76. }
  77.  
  78. void PlayAudioRecord(AudioClip newAudioClip)
  79. {
  80. audioSource.clip = newAudioClip;
  81. audioSource.Play();
  82. }
  83. }

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

                               

Unity Microphone 无限时长录制的更多相关文章

  1. Unity Microphone 录音时 检测声音大小

    刚开始以为只取录音时的最后一个sample来判断音量大小,发现都检测不到. 后来搜索了一下,原来需要取一段sample来判断,有的是这一段取平均值作为音量大小.我这里是取出一段sample中的峰值(p ...

  2. Unity3D中通过Animator动画状态机获取任意animation clip的准确播放持续时长

    Unity3d 4及之前的版本中动画的播放用的animation,可直接获取其播放持续长度.但5.x及以后的版本中都是用animator来播放动画了. https://docs.unity3d.com ...

  3. iOS:Gif动画功能(显示gif动画、获取gif动画时长、获取gif动画执行次数)

    一.简单介绍 gif动画是iOS开发中很常用的一个功能,有的是为了显示加载视频的过程,更多的是为了显示一个结果状态(动画更直观). 那么如何执行gif动画,方法有很多.(这里只写一下方法三,前两种之前 ...

  4. vue+uniapp实现美颜拍照录像,相册选择 | 录像限制时长,美颜拍照录像

    一.插件简介 Zhimi-BeautyCamera(智密 - 美颜相机图册插件)是一个支持美颜录像,美颜拍照,选择图视频功能,带录像参数时长限制的uniapp原生插件.平台支持:Android.IOS ...

  5. 【Android端 APP 启动时长获取】启动时长获取方案及具体实施

    一.什么是启动时长? 1.启动时长一般包括三种场景,分别是:新装包的首次启动时长,冷启动时长.热启动时长 冷启动 和 热启动 : (1)冷启动:当启动应用时,后台没有该程序的进程,此时启动的话系统会分 ...

  6. js读写Cookie问题(Cookie存储时长、Cookie存储域)汇总

    在采集网站用户行为数据/使用js对用户行为做交互时,经常会使用到Cookie,了解Js Cookie的读写,以及一些细节,非常重要.   什么是Cookie 所谓Cookie,只是一条极为短小的信息, ...

  7. js计算在线时长

    后台传来毫秒,前台转换成对应的时分秒 //在线时长 function longTime(seconds){ //总秒数 //seconds=seconds/1000; //得到小时 var hour ...

  8. js获取html5 audio 音频时长方法

    <audio src="我的好兄弟.mp3" controls="controls"  id="audio" style=" ...

  9. windows 7 下,如何统计某文件夹下 视频总时长

    由于项目需要,我需要给系统加权限,这真是一个让人头疼的问题,如果要每个业务方法都加上权限判断逻辑,那真的不敢想象是多么大的工作量,日后有变动的话,我会不会发疯? 所以我必须利用之前学到的AOP编程,在 ...

随机推荐

  1. HDU 1756 Cupid's Arrow( 判断点在多边形的内外 )

    链接:传送门 思路:判断每支箭是否在多边形内,计算几何点定位中水题,不清楚下面的代码能不能适用于给定点的顺序不确定( 既不是顺时针又不是逆时针 ) /************************* ...

  2. centos7最小化安装Oracle11gR2

    1.准备CentOS 7 系统环境 我以 CentOS-7-x86_64-DVD-1511.iso 为例,简述Oracle 11g的安装过程. 由于是使用静默模式(silent)安装的,无需使用图形化 ...

  3. pytorch 4 regression 回归

    import torch import torch.nn.functional as F import matplotlib.pyplot as plt # torch.manual_seed(1) ...

  4. MySQL 数据备份与还原 转载

    MySQL 数据备份与还原 一.数据备份 1.使用mysqldump命令备份 mysqldump命令将数据库中的数据备份成一个文本文件.表的结构和表中的数据将存储在生成的文本文件中. mysqldum ...

  5. tortoiseGit怎么记住密码

    tortoiseGit每次pull和push的时候都要输入git密码很是麻烦,下面是tortoiseGit记住密码的步骤 首先在你的项目界面右键 选择setting,这个步骤知识看一下你的名称和ema ...

  6. NYIST 973 天下第一

    天下第一时间限制:1000 ms | 内存限制:65535 KB难度:3 描述AC_Grazy一直对江湖羡慕不已,向往着大碗吃肉大碗喝酒的豪情,但是“人在江湖漂,怎能 不挨刀",”人在江湖身 ...

  7. oracle 时间戳TIMESTAMP

    //数据库 UPDATETIMESTAMP TIMESTAMP(6) //dto /** 更新时间戳 **/ private String updatetimestamp; //dao //插入操作 ...

  8. Understanding The Complete Story of Postback in ASP.NET

    https://docs.microsoft.com/zh-cn/dotnet/api/system.web.ui.page.ispostback?view=netframework-4.7 http ...

  9. web security

    brute force cracking   暴力破解 Brute force (also known as brute force cracking) is a trial and error me ...

  10. zzulioj--1708--01串也疯狂之光棍也有伴(dp)

    1708: 01串也疯狂之光棍也有伴 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 199  Solved: 50 SubmitStatusWeb B ...