原创文章:转载请标明出处--博客园 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,,);
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 * / && micPosition < length; });//保存前半段
micDataTemp = new float[length / ];
micClip.GetData(micDataTemp, );
micDataList.AddRange(micDataTemp);
isSaveFirstHalf = !isSaveFirstHalf;
}
else
{
yield return new WaitUntil(() => { micPosition = Microphone.GetPosition(micName); return micPosition > length / && micPosition < length / ; });//保存后半段
micDataTemp = new float[length/];
micClip.GetData(micDataTemp, length / );
micDataList.AddRange(micDataTemp);
isSaveFirstHalf = !isSaveFirstHalf;
} }
micPosition = Microphone.GetPosition(micName);
if (micPosition <= length)//前半段
{
micDataTemp = new float[micPosition/];
micClip.GetData(micDataTemp, );
}
else
{
micDataTemp = new float[micPosition - length/];
micClip.GetData(micDataTemp, length/);
}
micDataList.AddRange(micDataTemp);
Microphone.End(micName);
AudioClip newAudioClip = AudioClip.Create("RecordClip", micDataList.Count, , , false);
newAudioClip.SetData(micDataList.ToArray(), );
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 无限时长录制的更多相关文章

  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. springboot的几个缓存相关注解

    @Cacheable:查询 几个属性: ​ cacheNames/value:指定缓存组件的名字: ​ key:缓存数据使用的key,可以用来指定.默认即使用方法参数的值 ​ keyGenerator ...

  2. Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?

    Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别? 1.什么是Set?(what) Set是Collection容器的一个子接口,它不允许出现 ...

  3. ASP.NET-属性与过滤器

    目的:在调用操作之前或者之后执行特定的逻辑代码 系统定义: 1.日志记录 2.防图像盗链  3.爬虫 4.本地化,用于设定区域设置 5.动态操作,用于将操作注入到控制器当中 用来过滤HTTP请求 高级 ...

  4. LeetCode211:Add and Search Word - Data structure design

    Design a data structure that supports the following two operations: void addWord(word) bool search(w ...

  5. Detours改动段属性漏洞

    v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...

  6. 哈理工2015暑假训练赛 zoj 2078Phone Cell

    Phone CellTime Limit:10000MS    Memory Limit:32768KB    64bit IO Format:%lld & %llu SubmitStatus ...

  7. 百度地图-----&gt;地图类型、定位模式、实时交通、我的位置、加入覆盖物、覆盖物详情及提示

    在百度地图开发平台 http://developer.baidu.com/map/index.php? title=androidsdk 进行创建应用,获取应用的AK,在进行下载BaiduLBS_An ...

  8. Linux下DNS服务器搭建详解

    Linux下DNS服务器搭建详解 DNS  即Domain Name System(域名系统)的缩写,它是一种将ip地址转换成对应的主机名或将主机名转换成与之相对应ip地址的一种机制.其中通过域名解析 ...

  9. Linux就该这么学 20181005(第七章磁盘管理)

    参考链接https://www.linuxprobe.com lsblk检测硬盘使用情况 RAID 技术把多块物理硬盘设备(至少两块)通过硬件或软件的方式串联在一起,组成一个大的卷组,并将数据依次写入 ...

  10. BZOJ 3160 FFT+Manacher

    思路: 这道题思路好奇怪--. 我们先要知道关于x (x可以是间隙) 对称的有几对字母 显然暴力是n^2的 那怎么办呢 先把所有'a'看成1 'b'看成0 意外的发现 这不就是卷积嘛 再倒过来搞一搞 ...