借鉴:http://blog.csdn.net/zgyulongfei/article/details/7538523 博客详细结束了SPS和PPS的获取
http://blog.csdn.net/zblue78/article/details/6083374 文章【Android 的视频编码 H263 MP4V H264】的代码实现
http://blog.csdn.net/jzl19901027/article/details/9864351 Android MediaRecorder H264 编码实时视频流不能播放(readInt()值太大)的问题
再利用mediarecorder录制视频过程中,首先录制一段钟视频数据后,将数据流传入StsBox对象,调用getMdat()即可得到mdat的合适的开始位置和结束位置
............
try {
fis = receiver.getInputStream();
Thread.currentThread().sleep(500);
} catch (IOException e2) {
e2.printStackTrace();
return;
} catch (InterruptedException e) {
e.printStackTrace();
}
releaseVideo();
StsdBox stsdBox = new StsdBox(fis);
// stsdBox.saveStsBoxHead(context);
stsdBox.getMdat();
Log.i(TAG, "mdat: " + (stsdBox.getEndMdat() - stsdBox.getStartMdat()));
............
代码:
public class StsdBox {
private byte[] buffer = new byte[1024 * 64];
private int spsStartPos;
private int spsLength;
private int num, number = 0;
private int frame_size = 1024;
public StsdBox(InputStream fis) {
initByte(fis);
}
private void initByte(InputStream fis) {
while (true) {
try {
if(number >= buffer.length) {
break;
}
num = fis.read(buffer, number, frame_size);
number += num;
if (num < frame_size) {
break;
}
} catch (IOException e) {
e.printStackTrace();
Log.i("number: ", "" + number);
break;
}
}
}
private int startMdat = 0;
private int endMdat = 0;
public int getStartMdat() {
return startMdat;
}
public void setStartMdat(int startMdat) {
this.startMdat = startMdat;
}
public int getEndMdat() {
return endMdat;
}
public void setEndMdat(int endMdat) {
this.endMdat = endMdat;
}
public void getMdat() {
for(int im=0; im < buffer.length; im++) {
if (buffer[im] == 'm' && buffer[im + 1] == 'd'
&& buffer[im + 2] == 'a'
&& buffer[im + 3] == 't') {
if(im > 0 && buffer[im - 1] == '?') {
startMdat = im - 4;
} else {
startMdat = im;
}
if(im < (buffer.length - 1) && buffer[im + 5] == '?') {
if(buffer[im + 9] == '?') {
endMdat = im + 12;
} else {
endMdat = im + 8;
}
} else {
endMdat = im + 4;
}
break;
}
}
}
private int getAvcC() {
byte[] avcC = new byte[] { 0x61, 0x76, 0x63, 0x43 };
int avcRecord = 0;
for (int ix = 0; ix < buffer.length; ++ix) {
if (buffer[ix] == avcC[0] && buffer[ix + 1] == avcC[1]
&& buffer[ix + 2] == avcC[2]
&& buffer[ix + 3] == avcC[3]) {
avcRecord = ix + 4;
break;
}
}
if (0 == avcRecord) {
System.out.println(R.string.no_found_avcc);
avcRecord = 0;
}
return avcRecord;
}
public byte[] findSPS() {
if(getAvcC() == 0) {
return null;
}
spsStartPos = getAvcC() + 6;
byte[] spsbt = new byte[] { buffer[spsStartPos],
buffer[spsStartPos + 1] };
spsLength = CalculateUtil.bytes2Int(spsbt);
byte[] h264sps = new byte[spsLength];
// ���2���ֽڵ� sequenceParameterSetLength
spsStartPos += 2;
System.arraycopy(buffer, spsStartPos, h264sps, 0, spsLength);
printResult("SPS", h264sps, spsLength);
return h264sps;
}
public byte[] findPPS() {
if(getAvcC() == 0) {
return null;
}
int ppsStartPos = spsStartPos + spsLength + 1;
byte[] ppsbt = new byte[] { buffer[ppsStartPos],
buffer[ppsStartPos + 1] };
int ppsLength = CalculateUtil.bytes2Int(ppsbt);
byte[] h264pps = new byte[ppsLength];
ppsStartPos += 2;
System.arraycopy(buffer, ppsStartPos, h264pps, 0, ppsLength);
printResult("PPS", h264pps, ppsLength);
return h264pps;
}
private void printResult(String type, byte[] bt, int len) {
System.out.println(type + "������" + len);
String cont = type + "��������";
System.out.print(cont);
for (int ix = 0; ix < len; ++ix) {
System.out.printf("%02x ", bt[ix]);
}
System.out.println("\n----------");
}
}