package com.example.ffmpegaudio;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.nio.Buffer;
import android.app.Activity;
import android.media.MediaRecorder;
import android.net.LocalServerSocket;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private MediaRecorder mediarecorder;
private LocalSocket sender;
private LocalSocket received;
private LocalServerSocket lss;
private static final int BUFFER_SIZE=5000;
Button sendButton;
Button receivedButton;
private InputStream inputStream;
private Recoder recoder;
byte[] buffer;
private BufferedOutputStream bufferedoutstream;
private RandomAccessFile raf;
private boolean ISrunning;
private Thread getAudio;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendButton=(Button)findViewById(R.id.send);
receivedButton=(Button)findViewById(R.id.received);
sendButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.e("fdsa", "start button.....");
ISrunning=true;
recoder=new Recoder();
recoder.start();
MediaRecoderInit();
getAudio=new GetAudio();
getAudio.start();
}
});
receivedButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.e("fdsa", "stop the recording...");
ISrunning=false;
if (recoder!=null) {
recoder.interrupt();
}
if(mediarecorder!=null){
mediarecorder.stop();
mediarecorder.release();
mediarecorder=null;
}
if (inputStream!=null) {
try {
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
inputStream=null;
}
}
});
}
private void MediaRecoderInit(){
//设置MediaRecoder
File file=new File("/sdcard/LocalSocket.aac");
try {
raf=new RandomAccessFile(file, "rw");
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (mediarecorder==null) {
mediarecorder=new MediaRecorder();
}
mediarecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediarecorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);
mediarecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mediarecorder.setOutputFile(sender.getFileDescriptor());
try {
mediarecorder.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mediarecorder.start();
}
class GetAudio extends Thread{
byte[] buffer=new byte[1024];
int length=0;
int len=0;
int readlength=0;
public void run() {
try {
while(ISrunning){
while(readlength<1024){
readlength +=inputStream.read(buffer,readlength,1024-readlength);
Log.v("fds", "readlength--->"+readlength);
}
raf.write(buffer,0,readlength);
readlength=0;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
}
class Recoder extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
//localsocket可以类比socket,在源(mediaRcoder.setOutputFile(sender.getFileDescriptor()))中
//使用serversocket,发送本地,用socket在本地接收,得到的就是流;
//在本地用InputStream inprutstream = receiver.getInputStream();在本地得到流
received=new LocalSocket();
try {
lss=new LocalServerSocket("today_Socket");//相当于serversocekt开端口
received.connect(new LocalSocketAddress("today_Socket"));//相当于socket客户端
received.setReceiveBufferSize(BUFFER_SIZE);
received.setSendBufferSize(BUFFER_SIZE);
sender=lss.accept();//相当于serversocket等待连接,成功返回一个localsocket
sender.setReceiveBufferSize(BUFFER_SIZE);
sender.setSendBufferSize(BUFFER_SIZE);
inputStream=received.getInputStream();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Log.v("fdsa", "recoding audio....");
}
}
}
注意:(1)在配置文件中添加读取外部设备(内存卡)权限和MIC权限。
(2)在MainActivity中不要放while死循环,否则造成(主频高的CPU无响应、差的CPU直接卡死)
(3)Inputstream.read时要注意:
InputStream.read(byte[] b)和InputStream.read(byte[] b,int off,int len)这两个方法都是用来从流里读取多个字节的,有经验的程序员就会发现,这两个方法经常 读取不到自己想要读取的个数的字节。比如第一个方法,程序员往往希望程序能读取到b.length个字节,而实际情况是,系统往往读取不了这么多。仔细阅读Java的API说明就发现了,这个方法 并不保证能读取这么多个字节,它只能保证最多读取这么多个字节(最少1个)。因此,如果要让程序读取count个字节,最好用以下代码:
byte[] b = new byte[count];
int readCount = 0; // 已经成功读取的字节的个数
while (readCount < count) {
readCount += in.read(bytes, readCount, count - readCount);
}
用这段代码可以保证读取count个字节,除非中途遇到IO异常或者到了数据流的结尾(EOFException)