Unity Microphone 无限时长录制
原创文章:转载请标明出处--博客园 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 无限时长录制的更多相关文章
- Unity Microphone 录音时 检测声音大小
刚开始以为只取录音时的最后一个sample来判断音量大小,发现都检测不到. 后来搜索了一下,原来需要取一段sample来判断,有的是这一段取平均值作为音量大小.我这里是取出一段sample中的峰值(p ...
- Unity3D中通过Animator动画状态机获取任意animation clip的准确播放持续时长
Unity3d 4及之前的版本中动画的播放用的animation,可直接获取其播放持续长度.但5.x及以后的版本中都是用animator来播放动画了. https://docs.unity3d.com ...
- iOS:Gif动画功能(显示gif动画、获取gif动画时长、获取gif动画执行次数)
一.简单介绍 gif动画是iOS开发中很常用的一个功能,有的是为了显示加载视频的过程,更多的是为了显示一个结果状态(动画更直观). 那么如何执行gif动画,方法有很多.(这里只写一下方法三,前两种之前 ...
- vue+uniapp实现美颜拍照录像,相册选择 | 录像限制时长,美颜拍照录像
一.插件简介 Zhimi-BeautyCamera(智密 - 美颜相机图册插件)是一个支持美颜录像,美颜拍照,选择图视频功能,带录像参数时长限制的uniapp原生插件.平台支持:Android.IOS ...
- 【Android端 APP 启动时长获取】启动时长获取方案及具体实施
一.什么是启动时长? 1.启动时长一般包括三种场景,分别是:新装包的首次启动时长,冷启动时长.热启动时长 冷启动 和 热启动 : (1)冷启动:当启动应用时,后台没有该程序的进程,此时启动的话系统会分 ...
- js读写Cookie问题(Cookie存储时长、Cookie存储域)汇总
在采集网站用户行为数据/使用js对用户行为做交互时,经常会使用到Cookie,了解Js Cookie的读写,以及一些细节,非常重要. 什么是Cookie 所谓Cookie,只是一条极为短小的信息, ...
- js计算在线时长
后台传来毫秒,前台转换成对应的时分秒 //在线时长 function longTime(seconds){ //总秒数 //seconds=seconds/1000; //得到小时 var hour ...
- js获取html5 audio 音频时长方法
<audio src="我的好兄弟.mp3" controls="controls" id="audio" style=" ...
- windows 7 下,如何统计某文件夹下 视频总时长
由于项目需要,我需要给系统加权限,这真是一个让人头疼的问题,如果要每个业务方法都加上权限判断逻辑,那真的不敢想象是多么大的工作量,日后有变动的话,我会不会发疯? 所以我必须利用之前学到的AOP编程,在 ...
随机推荐
- My97 DatePicker获取自定义日期的前一天
1.控件,获取第一个input中的时间,再将这个时间的前一天赋值给第二个input <input type="text" class="form-control i ...
- 小学生都能学会的python(列表[ ])
小学生都能学会的python(列表[ ]) 1. 什么是列表(list) 能装东西的东西 列表中装的数据是没有限制的, 大小基本上是够用的 列表使用[]来表示. 在列表中每个元素与元素之间用逗号隔开 ...
- java静态方法
静态方法(全局方法)不能访问this(当前对象)它和类没有关系,会有逻辑错误,当调用静态方法的时候不需要创建对象 可以直接为boolean result = MyTest.isPrime();直接访问 ...
- HDU 4321 Contest 3
题意:给定a和b,n,让你求b+a, b+2*a, .......b+n*a里面有多少1. 当统计第K位的时候 可以注意到 第 B+T*A 和 B+(T+2^(K+1))*A 位是相同的 那么 第K位 ...
- [Chromium]怎样安全的使用PostTask
PostTask參数决策树 怎样传递绑定的对象 官方的解释总是最权威.有疑问看这里或者直接看代码中的说明: bind_helpers.h. 传值方式 描写叙述 this 或 对象指针 假设对象本身是一 ...
- Windows 8.1硬盘安装Ubuntu 14.04双系统
Windows 8.1硬盘安装Ubuntu 14.04双系统 学习了: http://www.jb51.net/os/windows/298507.html http://www.linuxidc.c ...
- POJ 1281 MANAGER
MANAGER Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Description O ...
- Codeforces Round #311 (Div. 2)题解
A. Ilya and Diplomas time limit per test 1 second memory limit per test 256 megabytes input standard ...
- 16.boost图深度优先遍历DFS
#include <iostream> #include <boost/config.hpp> //图(矩阵实现) #include <boost/graph/adjac ...
- DateForamt和SimpleDateFormat
1.因为DateFormat是抽象类,所以只能用子类来初始化 DateFormat df = new SimpleDateFormat("yyyy--MM--dd HH:MM:ss,属于本年 ...