VoAACEncoder 是提取自AOSP 2.3项目libstagefright内的AAC编码器。
现在封装为jni库在Android项目中调用,主要用于需要将语音编码为AAC ADTS流实时发布的场景。
该库充分利用了ARM汇编指令,比之前移植的FAAC库具有更高的编码效率。
实测QSD8250处理器下,16000 采样,32k bitRate,单声道编码 cpu占用只有2%~4%
使用方法:
将libVoAACEncoder.so 放入libs/armeabi 目录
将VoAACEncoder.java 放入com.sinaapp.bashell包下
示例代码:
Java
public class MainActivity extends Activity {
private AudioRecord recordInstance;
private boolean isStart;
private FileOutputStream fos;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
fos = new FileOutputStream("/sdcard/testAAC.aac");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
VoAACEncoder vo = new VoAACEncoder();
vo.Init(44100, 32000, (short)1, (short)1);// 采样率:44100,bitRate:32k,声道数:1,编码:0.raw 1.ADTS
int min = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
if(min<2048) {
min=2048;
}
byte[] tempBuffer = new byte[2048];
recordInstance = new AudioRecord(MediaRecorder.AudioSource.MIC, 44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, min);
recordInstance.startRecording();
isStart = true;
while (isStart) {
int bufferRead = recordInstance.read(tempBuffer, 0, 2048);
byte[] ret = vo.Enc(tempBuffer);
if (bufferRead > 0) {
System.out.println("ret:"+ret.length);
try {
fos.write(ret);
} catch (IOException e) {
e.printStackTrace();
}
}
}
recordInstance.stop();
recordInstance.release();
recordInstance = null;
vo.Uninit();
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
@Override
protected void onDestroy() {
isStart = false;
super.onDestroy();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
publicclassMainActivityextendsActivity{
privateAudioRecordrecordInstance;
privatebooleanisStart;
privateFileOutputStreamfos;
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try{
fos=newFileOutputStream("/sdcard/testAAC.aac");
}catch(FileNotFoundExceptione){
// TODO Auto-generated catch block
e.printStackTrace();
}
newThread(newRunnable(){
@Override
publicvoidrun(){
VoAACEncodervo=newVoAACEncoder();
vo.Init(44100,32000,(short)1,(short)1);// 采样率:44100,bitRate:32k,声道数:1,编码:0.raw 1.ADTS
intmin=AudioRecord.getMinBufferSize(44100,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT);
if(min<2048){
min=2048;
}
byte[]tempBuffer=newbyte[2048];
recordInstance=newAudioRecord(MediaRecorder.AudioSource.MIC,44100,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT,min);
recordInstance.startRecording();
isStart=true;
while(isStart){
intbufferRead=recordInstance.read(tempBuffer,0,2048);
byte[]ret=vo.Enc(tempBuffer);
if(bufferRead>0){
System.out.println("ret:"+ret.length);
try{
fos.write(ret);
}catch(IOExceptione){
e.printStackTrace();
}
}
}
recordInstance.stop();
recordInstance.release();
recordInstance=null;
vo.Uninit();
try{
fos.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}).start();
}
@Override
protectedvoidonDestroy(){
isStart=false;
super.onDestroy();
}
}
请不要忘记开启权限
XHTML
1
2
————2015年7月30日的分割线————-
时隔3年,撸主在整理硬盘时找到此项目,不少朋友感兴趣,也没什么好保留的,就开源吧。
https://github.com/illuspas/VoAACEncoder
原创文章,转载请注明: 转载自贝壳博客