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编程,在 ...
随机推荐
- HDU 1222 Wolf and Rabbit( 简单拓欧 )
链接:传送门 题意:狼抓兔子,狼从 0 出发沿逆时针寻找兔子,每走一步的距离为 m ,所有洞窟的编号为 0 - n-1 ,问是否存在一个洞窟使得兔子能够安全躲过无数次狼的搜捕. 思路:简单的拓展欧几里 ...
- JAVA 重载方法,参数为NULL时,调用的处理 (精确性原则)
引子:大家可以思考一下下面程序的输出结果 public class TestNull { public void show(String a){ System.out.println("St ...
- JavaScript 常见创建对象的方式
JavaScript 有哪几种创建对象的方式? javascript创建对象简单的说,无非就是使用内置对象或各种自定义对象,当然还可以用JSON:但写法有很多种,也能混合使用. (1)对象字面量的方式 ...
- Tomcat样例安全漏洞
[漏洞描述] Tomcat在使用的时候一般都直接官网下载源代码包直接使用. 默认情况下,Tomcat源码包里面包含了 examples 这个目录,这个目录主要实现一些样例页面的访问. 比如: ...
- WinServer-PowerShell基础
命令的参数: [-name] 这个参数必须要有,string表示name参数接受什么样的实参,<>表示参数可以接受的实参类型,通常出现set get add都会伴随着必须参数 [-name ...
- C++函数的导出与导入
DLL使用 (1)隐式链接到 DLL 的可运行文件在生成时链接到导入库(.lib文件). (2)採用显式连接(LoadLibrary和GetProcAddress)时,不须要.lib文件. 函数导出方 ...
- [Unit Testing] Configure the Angular CLI to use the Karma Mocha test reporter
Every Angular CLI generated project comes already with Karmapreinstalled as well a couple of executa ...
- CentOS6.3升级GCC到GCC4.8.2
server上安装的GCC版本号过旧.已经不满足个人使用的版本号需求,故决定对其进行升级操作.由当前版本号3.4.6升级到4.8.2.然受权限制约.仅仅能安装到个人文件夹.因此假设您的server能够 ...
- poj3352Road Construction 边双连通+伪缩点
/* 对于边双连通分支,求法更为简单. 仅仅需在求出全部的桥以后,把桥边删除.\ 原图变成了多个连通块,则每一个连通块就是一个边双连通分支. 桥不属于不论什么 一个边双连通分支,其余的边和每一个顶点都 ...
- swift -函数、函数指针
// // main.swift // FunctionTest-04 // import Foundation println("函数測试!") testFunction() / ...