package com.example.getaac264ts;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.media.MediaRecorder;
import android.net.LocalServerSocket;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements Callback, Runnable{
private static final String TAG = "H264_AAC";
private Camera mCamera;
Button sendButton;
Button receivedButton;
//初始化MediaRecorder
private MediaRecorder mMediaRecorder = null;
//private int videoWidth = 1280;
//private int videoHeight = 720;
private int videoWidth = 640;
private int videoHeight = 480;
private int videoRate = 25;
private String fd = "/sdcard/MediaRecorder/videotest.3gp";
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private boolean mMediaRecorderRecording = false;
LocalServerSocket lss;
LocalSocket receiver, sender;
private final int MAXFRAMEBUFFER = 20480;//20K
private byte[] h264frame = new byte[MAXFRAMEBUFFER];
private final byte[] head = new byte[]{0x00,0x00,0x00,0x01};
private RandomAccessFile file_test;
private byte[] SPS;
private byte[] PPS;
private int StartMdatPlace = 0;
public MediaRecorder mediarecorder;
public LocalSocket senderaac;
public LocalSocket receivedaac;
public LocalServerSocket lssaac;
public static final int BUFFER_SIZE=5000;
public InputStream inputStream;
public Recoder recoder;
byte[] buffer;
public BufferedOutputStream bufferedoutstream;
public RandomAccessFile raf;
public boolean ISrunning;
public Thread getAudio;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendButton=(Button)findViewById(R.id.start);
receivedButton=(Button)findViewById(R.id.stop);
InitSurfaceView();
InitMediaSharePreference();
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();
Log.e("fdsfd", "before the MediaRorder Init");
MediaRecoderInit();
Log.e("fdsfd", "after the MediaRorder Init");
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;
}
}
});
}
//初始化SurfaceView
private void InitSurfaceView() {
mSurfaceView = (SurfaceView) this.findViewById(R.id.surface_camera);
SurfaceHolder holder = mSurfaceView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mSurfaceView.setVisibility(View.VISIBLE);
}
//初始化,记录mdat开始位置的参数
SharedPreferences sharedPreferences;
private final String mediaShare = "media";
private void InitMediaSharePreference() {
sharedPreferences = this.getSharedPreferences(mediaShare, MODE_PRIVATE);
}
public void surfaceCreated(SurfaceHolder holder) {
mSurfaceHolder = holder;
initPreview();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
mSurfaceHolder = holder;
if(!mMediaRecorderRecording) {
InitLocalSocket();
Log.i(TAG, "before getSPSAndPPS()");
getSPSAndPPS();
initializeVideo();
startVideoRecording();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
mCamera.stopPreview();
mCamera.release();
mCamera = null;
mSurfaceHolder = null;
}
//初始化LocalServerSocket LocalSocket
private void InitLocalSocket(){
try {
lss = new LocalServerSocket("H264");
receiver = new LocalSocket();
receiver.connect(new LocalSocketAddress("H264"));
receiver.setReceiveBufferSize(500000);
receiver.setSendBufferSize(50000);
sender = lss.accept();
sender.setReceiveBufferSize(500000);
sender.setSendBufferSize(50000);
} catch (IOException e) {
Log.e(TAG, e.toString());
this.finish();
return;
}
}
//得到序列参数集SPS和图像参数集PPS,如果已经存储在本地
private void getSPSAndPPS(){
StartMdatPlace = sharedPreferences.getInt(
String.format("mdata_%d%d.mdat", videoWidth, videoHeight), -1);
Log.e(TAG, "StartMdatPlace---->"+StartMdatPlace);
if(StartMdatPlace != -1) {
byte[] temp = new byte[100];
try {
FileInputStream file_in = MainActivity.this.openFileInput(
String.format("%d%d.sps", videoWidth,videoHeight));
int index = 0;
int read=0;
while(true)
{
read = file_in.read(temp,index,10);
if(read==-1) break;
else index += read;
}
Log.e(TAG, "=====get sps length:"+index);
SPS = new byte[index];
System.arraycopy(temp, 0, SPS, 0, index);
file_in.close();
index =0;
//read PPS
file_in = MainActivity.this.openFileInput(
String.format("%d%d.pps", videoWidth,videoHeight));
while(true)
{
read = file_in.read(temp,index,10);
if(read==-1) break;
else index+=read;
}
Log.e(TAG, "==========get pps length:"+index);
PPS = new byte[index];
System.arraycopy(temp, 0, PPS, 0, index);
} catch (FileNotFoundException e) {
//e.printStackTrace();
Log.e(TAG, e.toString());
} catch (IOException e) {
//e.printStackTrace();
Log.e(TAG, e.toString());
}
} else {
Log.e(TAG,"==============StartMdatPlace = -1");
SPS = null;
PPS = null;
}
}
private boolean initializeVideo(){
if(mSurfaceHolder == null) {
return false;
}
mCamera.unlock();
mMediaRecorderRecording = true;
if(mMediaRecorder == null) {
mMediaRecorder = new MediaRecorder();
} else {
mMediaRecorder.reset();
}
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
//mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
//mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mMediaRecorder.setVideoSize(videoWidth, videoHeight);
mMediaRecorder.setVideoFrameRate(videoRate);
mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
mMediaRecorder.setMaxDuration(0);
mMediaRecorder.setMaxFileSize(0);
if(SPS==null)
{
Log.e(TAG, "============== SPS is null!!!!!!!!!!");
mMediaRecorder.setOutputFile(fd);
}
else
{
Log.e(TAG,"=============== SPS have value!!!!!!!");
mMediaRecorder.setOutputFile(sender.getFileDescriptor());
}
Log.i(TAG, "&&&&&&&&&&&&");
try {
mMediaRecorder.prepare();
Log.i(TAG, "before start()");
mMediaRecorder.start();
Log.i(TAG, "after start()");
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
releaseMediaRecorder();
}
Log.e(TAG, "chu shi hua MediaRecoder chen gong");
return true;
}
//释放MediaRecorder资源
private void releaseMediaRecorder(){
if(mMediaRecorder != null) {
if(mMediaRecorderRecording) {
mMediaRecorder.stop();
mMediaRecorderRecording = false;
}
mMediaRecorder.reset();
mMediaRecorder.release();
mMediaRecorder = null;
Log.i(TAG, "releaseMediaRecoder...");
}
}
//开始录像,启动线程
private void startVideoRecording() {
new Thread(this).start();
}
public void run() {
try {
if(SPS == null) {
Log.e(TAG, "Rlease MediaRecorder and get SPS and PPS");
Thread.sleep(1000);
//释放MediaRecorder资源
releaseMediaRecorder();
//从已采集的视频数据中获取SPS和PPS
findSPSAndPPS();
//找到后重新初始化MediaRecorder
initializeVideo();
}
DataInputStream dataInput = new DataInputStream(receiver.getInputStream());
//先读取ftpy box and mdat box, 目的是skip ftpy and mdat data,(decisbe by phone)
Log.e(TAG,"=============StartMdatPlace :" + StartMdatPlace);
//dataInput.read(h264frame, 0, StartMdatPlace);
dataInput.read(h264frame, 0, 28);
dataInput.skipBytes(16);
try {
File file = new File("/sdcard/MediaRecorder/MediaRecorder.264");
if (file.exists())
file.delete();
file_test = new RandomAccessFile(file, "rw");
} catch (Exception ex) {
Log.v("System.out", ex.toString());
}
file_test.write(head);
file_test.write(SPS);//write sps
file_test.write(head);
file_test.write(PPS);//write pps
int h264length =0;
while(mMediaRecorderRecording) {
h264length = dataInput.readInt();
Log.e(TAG, "h264 length :" + h264length);
int number=0 , num=0;
int frame_size = 1024;
file_test.write(head);
while(number"+h264length);
// byte[] h264 = new byte[h264length];
// System.arraycopy(h264frame, 0, h264, 0, h264length);
//
// file_test.write(head);
// file_test.write(h264);//write selice
}
file_test.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private void ReadSize(int h264length,DataInputStream dataInput) throws IOException, InterruptedException{
int read = 0;
int temp = 0;
while(read"+readlength);
}
raf.write(buffer,0,readlength);
readlength=0;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
}
public 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();在本地得到流
receivedaac=new LocalSocket();
try {
lss=new LocalServerSocket("today_Socket");//相当于serversocekt开端口
receivedaac.connect(new LocalSocketAddress("today_Socket"));//相当于socket客户端
receivedaac.setReceiveBufferSize(BUFFER_SIZE);
receivedaac.setSendBufferSize(BUFFER_SIZE);
senderaac=lss.accept();//相当于serversocket等待连接,成功返回一个localsocket
Log.i("fds", "sender init....");
senderaac.setReceiveBufferSize(BUFFER_SIZE);
senderaac.setSendBufferSize(BUFFER_SIZE);
inputStream=receivedaac.getInputStream();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Log.v("fdsa", "recoding audio....");
}
}
}