MediaMuxer編碼h264流文件

MediaMuxer mediaMuxer;
Map<Integer,Integer>map=new HashMap<>();
int save_x=0;
int time=0;
byte[]sps,pps;
int trackIndex;
MediaCodec mediaCodec=null;
class VideoToMp4 implements Runnable {
byte[] save;
int offset,length;

public VideoToMp4(byte[] save, int offset, int length) {
this.save = save;
this.offset = offset;
this.length = length;
}
@Override
public void run() {
int type=save[4]&0x1f;
 //判斷I幀,而後根據具體狀況獲取sps,pps
        if(type==7){            for (int i = 0; i < save.length-3; i++) {                if(save[i]==0&&save[i+1]==0&&save[i+2]==0&&save[i+3]==1){                    map.put(save_x,i);                    save_x++;                }            }            int length_sps=map.get(1)-map.get(0)-4;            int offset_sps=map.get(0)+3;            sps=new byte[length_sps];            System.arraycopy(save,offset_sps,sps,0,length_sps);            int length_pps=map.get(2)-map.get(1)-4;            int offset_pps=map.get(1)+3;            pps=new byte[length_pps];            System.arraycopy(save,offset_pps,pps,0,length_pps);        }        if(type==7){            BaseStatic.videoisStart=true;            BaseStatic.savaInfoToSD("video is Start");        }        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.JELLY_BEAN_MR2){            if (BaseStatic.videoisLaunch&&BaseStatic.videoisStart) {                synchronized (mediaMuxer) {                    if (x == 1) {                        BaseStatic.savaInfoToSD("videoformat is set");                        //MediaFormat 只設置一次,標誌「video/avc」表示h264.這裏不是MP4                        MediaFormat videoformat = MediaFormat.createVideoFormat("video/avc", dect[0], dect[1]);                        videoformat.setByteBuffer("csd-0", ByteBuffer.wrap(sps));                        videoformat.setByteBuffer("csd-1", ByteBuffer.wrap(pps));                        videoformat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar);                        videoformat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, dect[0] * dect[1]);                        videoformat.setInteger("capture-rate", 30);                        trackIndex = mediaMuxer.addTrack(videoformat);                        mediaMuxer.start();                        x++;                    }                    ByteBuffer byteBuffer;                    byteBuffer = ByteBuffer.allocate(length);                    byteBuffer.put(save);                    MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();                    bufferInfo.offset = 0;                    bufferInfo.size = length;                    time++;                    bufferInfo.flags = MediaCodec.BUFFER_FLAG_SYNC_FRAME;                    if(BaseStatic.videoisEnd){                        bufferInfo.flags = MediaCodec.BUFFER_FLAG_END_OF_STREAM;                    }            //時間戳必須遞增                    bufferInfo.presentationTimeUs = 1000000*time / 30;                    mediaMuxer.writeSampleData(trackIndex, byteBuffer, bufferInfo);                    if(BaseStatic.videoisEnd){                        time=0;                        x=0;                        BaseStatic.videoisStart=false;                        BaseStatic.videoisLaunch=false;                            BaseStatic.savaInfoToSD("mediaMuxer is stop");                            mediaMuxer.stop();                            BaseStatic.savaInfoToSD("mediaMuxer is release");                            mediaMuxer.release();                            mediaMuxer=null;                    }                }            }        }else{            MyMethod.ShowDialog(getActivity(),"您的手機版本過低(<4.4),沒法錄像");            BaseStatic.videoisLaunch=false;            BaseStatic.videoisStart=false;            mediaMuxer=null;        }    }}
相關文章
相關標籤/搜索