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

1. 编译apk

MainActivity.java:

package com.example.audiotest;

import java.io.FileOutputStream;
import java.io.IOException; import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button; public class MainActivity extends Activity {
private static String TAG = "JZJ";
AudioRecord mRecord = null;
boolean mReqStop = false; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
(new Thread() {
@Override
public void run() {
recordAndPlay();
}
}).start();
} private final int kSampleRate = 44100;
private final int kChannelMode = AudioFormat.CHANNEL_IN_STEREO;
private final int kEncodeFormat = AudioFormat.ENCODING_PCM_16BIT; private void init() {
int minBufferSize = AudioRecord.getMinBufferSize(kSampleRate, kChannelMode,
kEncodeFormat);
mRecord = new AudioRecord(MediaRecorder.AudioSource.REMOTE_SUBMIX,
kSampleRate, kChannelMode, kEncodeFormat, minBufferSize * 2);
} private final int kFrameSize = 2048;
private String filePath = "/sdcard/voice.pcm"; private void recordAndPlay() {
FileOutputStream os = null;
mRecord.startRecording();
try {
os = new FileOutputStream(filePath);
byte[] buffer = new byte[kFrameSize];
int num = 0;
while (!mReqStop) {
num = mRecord.read(buffer, 0, kFrameSize);
Log.d(TAG, "buffer = " + buffer.toString() + ", num = " + num);
os.write(buffer, 0, num);
} Log.d(TAG, "exit loop");
os.close();
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "Dump PCM to file failed");
}
mRecord.stop();
mRecord.release();
mRecord = null;
Log.d(TAG, "clean up");
} public void stop(View view) {
mReqStop = true;
Button stopBtn = (Button) findViewById(R.id.stopBtn);
stopBtn.setText("Stopped");
stopBtn.setEnabled(false);
}
}

布局文件activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" > <Button
android:id="@+id/stopBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="stop"
android:text="Stop" /> </RelativeLayout>

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

<?xml version="1.0" encoding="utf-8"?

>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.audiotest"
android:versionCode="1"
android:versionName="1.0" > <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"/> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.audiotest.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application> </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. catch异常

    int ret = -1; try { ret = tBuyerCodeApplyInfoService.insertTBuyerCodeApplyInfoBySelective(buyerCode) ...

  2. java SE 入门之输入输出(第四篇)

    在第一篇,八大基本类型的时候,我就介绍了输出,当然,这些输出都是简单的,后续写到流的时候,在细化输入输出. 现在只要求看懂输入输出.输入其实就是接受键盘的输入. public class Hello ...

  3. iOS交互h5— JavaScriptCore ---UIWebview

    JavaScriptCore这个框架,从而让web页面和本地原生应用交互起来非常方便,而且使用此框架可以做到Android那边和iOS相对统一, web前端 在三端交互中,web前端开发人员来定义,让 ...

  4. 浅谈JVM-图解类加载机制

    一.目录 二.类加载机制流程 1.什么是类加载机制? JVM把class文件加载到内存里面,并对数据进行校验.准备.解析和初始化,最终能够被形成被JVM可以直接使用的Java类型的过程. 2.类加载流 ...

  5. [合集]解决Python报错:local variable 'xxx' referenced before assignment

    a = 1 def use(): print(a) #输出1 引用不会报错 a = 1 def use(): a = 3 print(a) #输出 3 重新赋值也不会报错. 局部变量会优先在函数内部去 ...

  6. 前台提交数据(表单数据、Json数据及上传文件)的类型

    MIME (Multipurpose Internet Mail Extensions) 是描述内容类型的互联网标准.Clients use this content type or media ty ...

  7. html打造动画【系列2】- 可爱的蛙蛙表情

    先感受一下全部表情包: 在开始之前先安利一个知识点:Flex弹性布局 我们一般做水平三列布局都是用的float方法,将每一块浮动显示在同一行.这种方法会导致元素没有原来的高度属性,要用清除浮动来解决空 ...

  8. flutter圆角效果的实现

    new Material( borderRadius: BorderRadius.circular(20.0), shadowColor: Colors.blue.shade200, elevatio ...

  9. android中的ellipsize

    textview中有个内容过长加省略号的属性,即ellipsize 用法如下: 在xml中 android:ellipsize = "end" 省略号在结尾 android:ell ...

  10. 5maven工程莫名其妙只在项目名称那里有一个红叉

    manven工程里面没有报错的地方,编译也没有问题,只是项目名称那里有一个红叉.   解决办法:   右击项目-->maven-->update project   注意: 这种方法有时可 ...