通过API 19新加的MediaRecorder.AudioSource.REMOTE_SUBMIX參数能够让系统App录制系统内置的声音,也就是扬声器的声音。以下是一个巨简单的样例来演示样例怎样通过AudioRecord配合REMOTE_SUBMIX參数进行录制。

1. 编译apk

MainActivity.java:

  1. package com.example.audiotest;
  2. import java.io.FileOutputStream;
  3. import java.io.IOException;
  4. import android.app.Activity;
  5. import android.media.AudioFormat;
  6. import android.media.AudioRecord;
  7. import android.media.MediaRecorder;
  8. import android.os.Bundle;
  9. import android.util.Log;
  10. import android.view.View;
  11. import android.widget.Button;
  12. public class MainActivity extends Activity {
  13. private static String TAG = "JZJ";
  14. AudioRecord mRecord = null;
  15. boolean mReqStop = false;
  16. @Override
  17. protected void onCreate(Bundle savedInstanceState) {
  18. super.onCreate(savedInstanceState);
  19. setContentView(R.layout.activity_main);
  20. init();
  21. (new Thread() {
  22. @Override
  23. public void run() {
  24. recordAndPlay();
  25. }
  26. }).start();
  27. }
  28. private final int kSampleRate = 44100;
  29. private final int kChannelMode = AudioFormat.CHANNEL_IN_STEREO;
  30. private final int kEncodeFormat = AudioFormat.ENCODING_PCM_16BIT;
  31. private void init() {
  32. int minBufferSize = AudioRecord.getMinBufferSize(kSampleRate, kChannelMode,
  33. kEncodeFormat);
  34. mRecord = new AudioRecord(MediaRecorder.AudioSource.REMOTE_SUBMIX,
  35. kSampleRate, kChannelMode, kEncodeFormat, minBufferSize * 2);
  36. }
  37. private final int kFrameSize = 2048;
  38. private String filePath = "/sdcard/voice.pcm";
  39. private void recordAndPlay() {
  40. FileOutputStream os = null;
  41. mRecord.startRecording();
  42. try {
  43. os = new FileOutputStream(filePath);
  44. byte[] buffer = new byte[kFrameSize];
  45. int num = 0;
  46. while (!mReqStop) {
  47. num = mRecord.read(buffer, 0, kFrameSize);
  48. Log.d(TAG, "buffer = " + buffer.toString() + ", num = " + num);
  49. os.write(buffer, 0, num);
  50. }
  51. Log.d(TAG, "exit loop");
  52. os.close();
  53. } catch (IOException e) {
  54. e.printStackTrace();
  55. Log.e(TAG, "Dump PCM to file failed");
  56. }
  57. mRecord.stop();
  58. mRecord.release();
  59. mRecord = null;
  60. Log.d(TAG, "clean up");
  61. }
  62. public void stop(View view) {
  63. mReqStop = true;
  64. Button stopBtn = (Button) findViewById(R.id.stopBtn);
  65. stopBtn.setText("Stopped");
  66. stopBtn.setEnabled(false);
  67. }
  68. }

布局文件activity_main.xml:

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. tools:context=".MainActivity" >
  6. <Button
  7. android:id="@+id/stopBtn"
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. android:onClick="stop"
  11. android:text="Stop" />
  12. </RelativeLayout>

配置文件AndroidManifest.xml,注意要加上的几个权限:

  1. <?xml version="1.0" encoding="utf-8"?
  2. >
  3. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  4. package="com.example.audiotest"
  5. android:versionCode="1"
  6. android:versionName="1.0" >
  7. <uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT" />
  8. <uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"/>
  9. <uses-permission android:name="android.permission.RECORD_AUDIO" />
  10. <uses-sdk
  11. android:minSdkVersion="19"
  12. android:targetSdkVersion="19" />
  13. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  14. <application
  15. android:allowBackup="true"
  16. android:icon="@drawable/ic_launcher"
  17. android:label="@string/app_name"
  18. android:theme="@style/AppTheme" >
  19. <activity
  20. android:name="com.example.audiotest.MainActivity"
  21. android:label="@string/app_name" >
  22. <intent-filter>
  23. <action android:name="android.intent.action.MAIN" />
  24. <category android:name="android.intent.category.LAUNCHER" />
  25. </intent-filter>
  26. </activity>
  27. </application>
  28. </manifest>

编译生成Test.apk。

2. 加系统签名

java -jar signapk.jar platform.x509.pem platform.pk8 ./Test.apk final.apk

platform.x509.pem和platform.pk8在Android源代码的build/target/product/security文件夹下。

signapk.jar能够从https://code.google.com/p/signapk/下载。

3. 安装签名好的apk,执行

启动时即開始採集系统声音数据,结束时点击Stopbutton停止。这时採集数据会导出到/sdcard/voice.pcm文件。

4. 取出音频採样数据,播放

adb pull /sdcard/voice.pcm 

vlc --demux=rawaud --rawaud-channels 2 --rawaud-samplerate 44100 voice.pcm

这样就開始播放刚才录制的声音了。vlc是一个多媒体播放器(http://www.videolan.org/vlc/index.html)。支持播放PCM数据。当然也能够用其他支持播放PCM的播放器。

总结来说。这样的方法的缺点是录制时扬声器就不能输出,长处是不用改系统层。假设要两个同一时候输出能够參考这篇文章:http://xzpeter.org/?p=254。

Android 4.4中AudioRecord用例 - 录制系统内置声音的更多相关文章

  1. Android音频处理——通过AudioRecord去保存PCM文件进行录制,播放,停止,删除功能

    Android音频处理--通过AudioRecord去保存PCM文件进行录制,播放,停止,删除功能 音频这方面很博大精深,我这里肯定讲不了什么高级的东西,最多也只是一些基础类知识,首先,我们要介绍一下 ...

  2. android中AudioRecord使用

    一 什么是音频的采样率和采样大小 自然界中的声音非常复杂,波形极其复杂,通常我们采用的是脉冲代码调制编码.即PCM编码.PCM通过抽样.量化.编码三个步骤将连续变化的模拟信号转换为数字编码. 抽样:在 ...

  3. Android短视频中如何实现720P磨皮美颜录制?

    视频中磨皮.美颜功能已成为刚需,那么如何在Android短视频中实现720P磨皮美颜录制?本篇文章中,网易云信资深开发工程师将向大家介绍具体的操作方法. 相关阅读推荐 <短视频技术详解:Andr ...

  4. 技术分享 | Appium 用例录制

    原文链接 下载及安装 下载地址: https://github.com/appium/appium-desktop/releases 下载对应系统的 Appium 版本,安装完成之后,点击 " ...

  5. Android音视频之MediaRecorder音视频录制

    前言: 公司产品有很多地方都需要上传音频视频,今天抽空总结一下音频视频的录制.学习的主角是MediaRecorder类. MediaRecorder类介绍: MediaRecorder类是Androi ...

  6. Eclipse与Android源码中ProGuard工具的使用

    由于工作需要,这两天和同事在研究android下面的ProGuard工具的使用,通过查看android官网对该工具的介绍以及网络上其它相关资料,再加上自己的亲手实践,算是有了一个基本了解.下面将自己的 ...

  7. Android源码中内置包含so文件的APK文件

    方法一: 在packages/apps下面以需要预置的APK名字创建文件夹,以预置一个名为Test的APK为例 将Test.apk放到packages/apps/Test下面 在packages/ap ...

  8. Unity在Android和iOS中如何调用Native API

    本文主要是对unity中如何在Android和iOS中调用Native API进行介绍. 首先unity支持在C#中调用C++ dll,这样可以在Android和iOS中提供C++接口在unity中调 ...

  9. android操作sdcard中的多媒体文件(一)——音乐列表的制作

    android操作sdcard中的多媒体文件(一)——音乐列表的制作 原文地址 最近做了一个android音乐播放器,个人感觉最难的就是“后台播放”以及有关“播放列表”的部分,但是总算是找到了实现的方 ...

随机推荐

  1. 图片切换(手动切换,imagelist的单独使用)

    //当前图片的索引 private int currIndex = 0; //判断上一个按钮和下一个按钮是否可用 private void SetEabled() { //如果当前显示的是第一张图片, ...

  2. CSS3 transition 过度

    一个元素在不同的状态之间进行平滑的交换 CSS3中使用transition属性实现过度效果 一个简单的例子: img{ background-image:url("img/1.jpg&quo ...

  3. 云服务器部署mongodb

    我喜欢用简单的方法 步骤 下载 解压并运行 远程连接测试 下载 到官方下载页获取下载地址,如图 在云服务器上,使用命令curl 你的地址 -o mongodb.tgz ,下载到当前目录,转到下一步. ...

  4. 郭霖 - MVVM开源项目学习

    https://blog.csdn.net/guolin_blog/article/details/87900605 https://medium.com/androiddevelopers/view ...

  5. ASP.NET MVC中你必须知道的13个扩展点

         ScottGu在其最新的博文中推荐了Simone Chiaretta的文章13 ASP.NET MVC extensibility points you have to know,该文章为我 ...

  6. js与native的交互

    WebView与Javascript交互(Android): WebView与Javascript交互是双向的数据传递,1.H5网页的JS函数调用Native函数 2.Native函数调用JS函数,具 ...

  7. chrome 浏览器调用 ocx 插件

    原文:http://blog.csdn.net/wangchao1988ok/article/details/45193489 IE 上使用 ocx 插件网上已经有很多资料说明,这里就不重复了,那如何 ...

  8. Spring手册

    一.Spring 简介 二.结构体系 三.七大主要模块 四.Spring Maven依赖 五 .Sprinf framework 一.Spring 简介 spring是一个开源的轻量级的应用开发框架, ...

  9. Oracle常见等待事件

    1Buffer busy waits从本质上讲,这个等待事件的产生仅说明了一个会话在等待一个Buffer(数据块),但是导致这个现象的原因却有很多种.常见的两种是: ·         当一个会话视图 ...

  10. linux centos5.8装yum安装mysql

     默认的yum安装mysql都是5.1版本的 想要安装5.7的可以进行配置rpm包进行, mysql5.7安装路径 下面是默认的5.1安装路径 首先我们在使用yum安装的的时候会默认使用最新安装的,最 ...