之前这个小车已经做出了一个框架,之后趁手头工作少点的时候,加紧做了下语音,目前基本已经实现我需要的功能了。
软件界面还是一种测试的界面,能用就行,美化软件我向来都不怎么样,一直搞单片机的,弄弄vs eclipse的不是很习惯。
前篇请参考地址:
http://blog.csdn.net/lynnlase/article/details/17246877
几个设计要点:
1.图像采用mjpg采集的图片,速度上我觉得的是够的。
2.tcp发送数据时注意采用byte[]数组,不要转成char[]型。
3.心跳包我是自己设计的10s一次。单独一个线程。
4.其他没有什么了,贴下部分java代码。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.main);
setContentView(R.layout.main);
InitView();
m_in_buf_size = android.media.AudioRecord.getMinBufferSize(8000,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
m_in_rec = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
m_in_buf_size);
m_out_buf_size = android.media.AudioTrack.getMinBufferSize(8000,
AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
m_out_trk = new AudioTrack(AudioManager.STREAM_MUSIC, 8000,
AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
m_out_buf_size, AudioTrack.MODE_STREAM);
m_in_bytes = new byte[m_in_buf_size];
m_keep_running = runflag = listenflag = false;
heartcount = 0;
btnBack.setEnabled(false);
btnCall.setEnabled(false);
btnGo.setEnabled(false);
btnLeft.setEnabled(false);
btnRight.setEnabled(false);
btnStop.setEnabled(false);
btnListen.setEnabled(false);
heartThread = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
// runflag = true;
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
heartcount++;
if (heartcount == 10) {
// msg = "lynnupup";
if (runflag) {
mPrintWriter.write("lynnlase");
mPrintWriter.flush();
}
heartcount = 0;
}
}
}
});
heartThread.start();
// myImageView.setImageResource(R.drawable.);
// Uri uri = Uri.parse("http://192.168.2.70:8080/?action=stream");
// video.setMediaController(new MediaController(this));
// video.setVideoURI(uri);
// videoView.start();
// video.requestFocus();
}
public void onClick(View bt) {
heartcount = 0;
String msg;
switch (bt.getId()) {
case R.id.btncall:
btnCall.setText("关闭声音");
if (!m_keep_running) {
newThread = new Thread(new Runnable() {
@Override
public void run() {
int bytes_read;
byte[] bytes_pkg;
int readsize = 0;
m_keep_running = true;
m_in_rec.startRecording();
while (m_keep_running) {
bytes_read = m_in_rec.read(m_in_bytes, 0,
m_in_buf_size);
if (AudioRecord.ERROR_INVALID_OPERATION != bytes_read) {
try {
// Log.v("lynn", str);
dos.write(m_in_bytes, 0, bytes_read);
dos.flush();
heartcount = 0;
} catch (IOException e) {
e.printStackTrace();
}
}
}
m_in_rec.stop();
}
});
newThread.start(); // 启动线程
} else {
m_keep_running = false;
btnCall.setText("开启声音");
// m_in_rec.stop();
// newThread.stop();
}
break;
case R.id.btnlisten:
if (!listenflag) {
listenflag = true;
btnListen.setText("关监听");
playThread = new Thread(new Runnable() {
@Override
public void run() {
int bytes_read = 0;
byte[] bytes_pkg = new byte[8192];
m_out_trk.play();
while (listenflag) {
try {
bytes_read=ios.read(bytes_pkg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (bytes_read > 0) {
m_out_trk.write(bytes_pkg, 0, bytes_read);
Log.v("lynn", String.valueOf(bytes_read));
}
}
m_out_trk.stop();
}
});
playThread.start(); // 启动线程
msg = "lynnlynn";
mPrintWriter.write(msg);
mPrintWriter.flush();
} else {
listenflag = false;
btnListen.setText("开监听");
msg = "lynnover";
mPrintWriter.write(msg);
mPrintWriter.flush();
}
break;
default:
break;
}
}
以上是oncreat處理以及onclick事件代碼,主要是音频部分。因为采集的都是pcm流,也可以实时录制成wav文件。
嵌入式部分简单了,2个线程实现收发功能就好。
效果如下:

基本告一段落了,其实家庭安防方面实现对讲,视频通话真的挺实用的,可以考虑做一套成熟的方案推广,虽然现在市场上其实也蛮多的。