AudioRecord报错startRecording() called on an uninitialized AudioRecord.总结
一、前言
最近写一个Android项目,想使用AudioRecord录制手机内部声音,但是调用开始录音的方法startRecording()
时,总是遇到这个错误:
startRecording() called on an uninitialized AudioRecord.
在此总结一下。
二、分析
1.百度发现,报这个错可能是AudioRecord没有初始化
(没有new)。正确写法可以这样写:
private AudioRecord mRecord = null;
private final int kFrameSize = 2048;
private final int kSampleRate = 44100;
private final int kChannelMode = AudioFormat.CHANNEL_IN_STEREO;
private final int kEncodeFormat = AudioFormat.ENCODING_PCM_16BIT;//标志位,通过修改这个,决定录音是否停止
public boolean mReqStop = true;public void recordAndPlay(File f) {//修改标志位,开始录音mReqStop = false;FileOutputStream os = null;if(mRecord == null) {int minBufferSize = AudioRecord.getMinBufferSize(kSampleRate, kChannelMode, kEncodeFormat);mRecord = new AudioRecord(MediaRecorder.AudioSource.REMOTE_SUBMIX, kSampleRate, kChannelMode, kEncodeFormat, minBufferSize * 2);//mRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, kSampleRate, kChannelMode, kEncodeFormat, minBufferSize * 2);}try {mRecord.startRecording();}catch (Exception e){Log.e("错误!",e.getMessage());return;}try {os = new FileOutputStream(f);byte[] buffer = new byte[kFrameSize];int num = 0;while (!mReqStop) {num = mRecord.read(buffer, 0, kFrameSize);os.write(buffer, 0, num);}os.close();} catch (IOException e) {Log.e("IO错误!",e.getMessage());}mRecord.stop();mRecord.release();mRecord = null;}
这个方法可以开始录音,保存为pcm文件。
这个方法已经确实把AudioRecord初始化了,但是还是会报错
。
2.继续百度,发现没有权限
也会报这个错,需要在AndroidManifest.xml增加权限
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT" /> <uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"/> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
3.为了保险,又在Android代码中增加了申请权限的方法
@SuppressLint("NewApi")private boolean checkAudio2(){if (checkSelfPermission(Manifest.permission.CAPTURE_AUDIO_OUTPUT) == PackageManager.PERMISSION_GRANTED){return true;}else{return false;}}@SuppressLint("NewApi")private void requestAudio2Permission() {if (!checkAudio2()) {requestPermissions(new String[]{Manifest.permission.CAPTURE_AUDIO_OUTPUT}, 0);} else {}}
然后给录音按钮增加了个功能,点击按钮时,调用requestAudio2Permission()方法,应该就出现申请权限的对话框才对,但是点击后没有反应
。
3.继续百度发现,MediaRecorder.AudioSource.REMOTE_SUBMIX
功能只有系统应用才能使用,不开放给其它应用。
因此按照教程,把apk重新签名为系统应用。
(1)在AndroidManifest.xml文件的application
标签中,增加配置:android:sharedUserId="android.uid.system"
(2)打release包,然后使用signapk.jar重新签名为系统应用。
●signapk.jar下载地址:
https://gitee.com/code_to_success/signapk.git
其中包含了platform.x509.pem与platform.pk8这2个文件。
●可以把自己打的release包改名为test.apk,然后执行下面的命令:
java -jar signapk.jar platform.x509.pem platform.pk8 ./test.apk final.apk
需要把相关文件放在命令中对应的路径下,然后生成的final.apk就是有系统签名的apk了。
备注:
那2个文件可以从android官网下载,platform.x509.pem和platform.pk8在Android源码的build/target/product/security目录下。
signapk.jar可以从https://code.google.com/p/signapk/下载。
注意这种方法录音时扬声器不能输出。
(3)安装apk测试,发现没有用,还是报错
。
不知道是不是由于platform.x509.pem和platform.pk8不是最新版的问题。
4.经过多次测试,使用MediaRecorder.AudioSource.MIC
、申请
Manifest.permission.RECORD_AUDIO
权限后,是可以正常使用手机录音功能的,不过录制的是麦克风
;
而使用MediaRecorder.AudioSource.REMOTE_SUBMIX
,无法申请Manifest.permission.CAPTURE_AUDIO_OUTPUT
权限、并且无法录音,报错:startRecording() called on an uninitialized AudioRecord
。
5.所以最后暂时没有实现录制手机内部声音的功能,改为了使用MIC参数、录制麦克风的声音。
三、总结
●AudioRecord报错startRecording() called on an uninitialized AudioRecord,可能是没有初始化AudioRecord
、没有申请权限
、使用REMOTE_SUBMIX等不开放给非系统应用的参数
导致的。
●目前暂时没有解决REMOTE_SUBMIX无法使用、无法录制手机内部声音的问题。
待后续研究。
四、后记
2021.9.26
1.关于录制手机内部声音问题
现在是android11版本,第三方软件实现手机内录功能比较困难,因此还是使用系统自带的录屏软件->选择录制内部声音
,然后使用视频音频提取APP,提取录屏视频中的音频为mp3的方式好些。
相关网址:
https://zhidao.baidu.com/question/396545963009870525.html
https://www.zhihu.com/question/265086051
2.关于AudioRecord使用的参数
可以使用以下参数:
//声音来源等参数
Audio Source: MIC
Sample rate: 16000
Number of channels: CHANNEL_CONFIGURATION_MONO
Format: ENCODING_PCM_16BIT
Buffer size: 16000 * 30 (30 second buffer)//Java中写法
AudioRecord mRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,16000,AudioFormat.CHANNEL_CONFIGURATION_MONO,AudioFormat.ENCODING_PCM_16BIT,16000*30);
AudioRecord报错startRecording() called on an uninitialized AudioRecord.总结相关推荐
- conda tensorflow_TensorFlow笔记1——补充附录(1) 机器学习相关库安装、使用中遇到的报错情况...
本文内容汇总 Anaconda(python3.7)和原生python3.7安装tensorflow 警告 AVX2 FMA 报错 'tensorflow' has no attribute 'xxx ...
- 【Tensorflow】报错:FailedPreconditionError: Attempting to use uninitialized value keep_prob_7
问题描述: 定义了一个变量: keep_prob = tf.Variable(1.0 , name='keep_prob') 尝试打印它的值: print(sess.run(keep_prob)) 报 ...
- 从零开始在ubuntu上安装和使用k8s集群及报错解决
文章目录 安装docker 安装kubernetes 配置k8s集群 配置虚拟机网络 配置Master节点的k8s网络 拉取k8s需要的镜像 启动 kubeadm 和 kubelet 配置 node节 ...
- Tensorflow运行程序报错 FailedPreconditionError
1 FailedPreconditionError错误现象 在运行tensorflow时出现报错,报错语句如下: FailedPreconditionError (see above for trac ...
- kibana常见启动报错
环境 :Ubuntu16.04 报错1.连接elasticsearch,kibana启动报错 报错信息 : Status changed from uninitialized to green - R ...
- bdd 启动 data processing进程报错 Can't locate LWP.pm in @INC
bdd 启动 data processing进程报错 Can't locate LWP.pm in @INC Can't locate LWP.pm in @INC (@INC contains: / ...
- redis.clients java_redis报错redis/clients/jedis/JedisPoolConfig'(curren
redis + Jedis + Spring报错Type 'redis/clients/jedis/JedisPoolConfig'(current frame, stack[4]) is not a ...
- 【ELK报错】Alias [.kibana] has more than one indices associated with it [[.kibana_1, .kibana_2]]
错误复现 搭建1套新的ELK环境,将之前旧的ES的索引文件data/nodes/0/indices/全部复制到新的ES中.期间不要停止ES.然后kibana就无法访问了,重启kibana报错如下: l ...
- 为什么我的程序debug版本运行没有问题,而release版本总是报错?
To 楼主 ,我在另外一个类似的贴子作了回答 http://expert.csdn.net/Expert/topic/2955/2955693.xml?temp=.3361933 ...
最新文章
- linux安全狗 nginx,linux 下 safedog 防护 Nginx
- hdu 1003 Max Sum
- jcache_窥探JCache API(JSR 107)
- Python爬虫十六式 - 第三式:Requests的用法
- allegro放置器件无法放_洗衣机放卫生间,这几种赶紧学起
- Android-Splash
- NULL指针的奇妙之旅
- Astar寻路教程!
- 数据分析sql面试必会6题经典_经典SQL面试题及答案分析
- Android实现AirPlay,DriodAirPlay开发
- 图像加密技术综述(常见的图像加密算法简介)
- 肠道微生物群:环境污染物毒性的重要参与者?
- 世界五大黑客:代码创造他们,他们改变世界!
- 经典Bug永流传---每周一“虫”(二十一)
- 服务器修改不了分辨率,ubuntu不能设置高分辨率问题的解决方法
- docker MySQL8
- python爬取所有页url_Python 如何爬取相同url下,多个页面的链接内容
- [SHELL]: ln 命令详解
- 一个普通玩家眼中的网博会
- VUE 学习之parent 选项