public class MediaMuxerCore {    public static final int TRACK_VIDEO = 0;    public static final int TRACK_AUDIO = 1;   private static MediaMuxerCore mediaMuxerCore;    private HandlerThread muxerHandlerThread;    private final Object syncOp = new Object();    private MuxerHandler muxerHandler;    public MediaMuxerCore() {        muxerHandlerThread = new HandlerThread("MediaMuxerCore,muxerHandlerThread");        muxerHandlerThread.start();        muxerHandler = new MuxerHandler(muxerHandlerThread.getLooper());    }    public static void startMuxer(String filePath){     //   saveFilePath = filePath;        LogTools.d("sent startMuxer");        if(mediaMuxerCore == null){            synchronized (MediaMuxerCore.class){                if (mediaMuxerCore == null){                    mediaMuxerCore = new MediaMuxerCore();                }            }        }        mediaMuxerCore.start(filePath);    }    public static void stopMuxer(){        synchronized (MediaMuxerCore.class){            if(mediaMuxerCore != null){                mediaMuxerCore.stop();                // mediaMuxerCore = null;                LogTools.d("sent stopMuxer");            }        }    }    public static MediaMuxerCore getInstance(){        if(mediaMuxerCore == null){            synchronized (MediaMuxerCore.class){                if (mediaMuxerCore == null){                    mediaMuxerCore = new MediaMuxerCore();                }            }        }        return mediaMuxerCore;    }    public void start(String saveFilePath){        synchronized (syncOp) {            muxerHandler.start(saveFilePath);        }    }    public void stop(){        synchronized (syncOp) {            muxerHandler.stop();        }    }    /**     * 添加音轨或视轨     * @param index     * @param mediaFormat     */    public void addTrackIndex(@TrackIndex int index, MediaFormat mediaFormat){        synchronized (syncOp) {            muxerHandler.addTrackIndex(index,mediaFormat);        }    }    /**     * 添加混合数据     * @param data     */    public void addMuxerData(MuxerData data){        synchronized (syncOp) {            muxerHandler.addMuxterData(data);        }    }    static class MuxerHandler extends Handler {        private int videoTrackIndex = -1;        private int audioTrackIndex = -1;        private boolean isVideoAdd;        private boolean isAudioAdd;        private MediaMuxer mediaMuxer;        private final static int MSG_START = 1;        private final static int MSG_ADD_TRACK = 2;        private final static int MSG_START_MUXER = 3;        private final static int MSG_WRITE = 4;        private final static int MSG_STOP = 5;        public MuxerHandler(Looper looper) {            super(looper);        }        private enum STATE {            IDLE,            READY,            RUNNING,            STOPPED        }        public void addTrackIndex(@TrackIndex int index, MediaFormat mediaFormat){            this.removeMessages(MSG_WRITE);            this.sendMessage(this.obtainMessage(MSG_ADD_TRACK,index,0,mediaFormat));        }        public void addMuxterData(MuxerData data){            this.sendMessage(this.obtainMessage(MSG_WRITE,data));        }        public void start(String path){            this.removeMessages(MSG_START);            this.removeMessages(MSG_WRITE);            this.sendMessage(this.obtainMessage(MSG_START,path));        }        public void stop(){            this.removeMessages(MSG_WRITE);            this.sendMessage(this.obtainMessage(MSG_STOP));        }        private STATE state;        @Override        public void handleMessage(Message msg) {            switch (msg.what) {                case MSG_START:                    LogTools.d("sent MSG_START");                    if (state == STATE.READY || state == STATE.RUNNING) {                        break;                    }                    String filePath = (String)msg.obj;                    isVideoAdd = false;                    isAudioAdd = false;                    try {                        mediaMuxer = new MediaMuxer(filePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);                    } catch (IOException e) {                        e.printStackTrace();                        mediaMuxer = null;                    }                    state = STATE.READY;                    LogTools.d("sent MuxerHandler state ready");                    break;                case MSG_ADD_TRACK:                    LogTools.d("sent MSG_ADD_TRACK");                    if (state != STATE.READY) {                        break;                    }                    if(mediaMuxer == null)                        return;                    int track = 0;                    MediaFormat mediaFormat = (MediaFormat) msg.obj;                    int index = msg.arg1;                    try {                        track = mediaMuxer.addTrack(mediaFormat);                    } catch (Exception e) {                        e.printStackTrace();                    }                    if(index == TRACK_VIDEO){                        videoTrackIndex = track;                        isVideoAdd = true;                        LogTools.d("sent 添加视轨完成");                    }else{                        audioTrackIndex = track;                        isAudioAdd = true;                        LogTools.d("sent 添加音轨完成");                    }                    if(isVideoAdd && isAudioAdd){                        mediaMuxer.start();                        state = STATE.RUNNING;                        LogTools.d("sent mediaMuxer start");                        LogTools.d("sent MuxerHandler state running");                    }                    break;                case MSG_WRITE:                    LogTools.d("sent MuxerHandler MSG_WRITE");                    if (state != STATE.RUNNING ){                        return;                    }                    MuxerData data = (MuxerData) msg.obj;                    int writeTrack = 0;                    if (data.trackIndex == TRACK_VIDEO) {                        writeTrack = videoTrackIndex;                    } else {                        writeTrack = audioTrackIndex;                    }                    try {                        mediaMuxer.writeSampleData(writeTrack, data.byteBuffer, data.bufferInfo);                        LogTools.d("sent写入混合数据,buffer.size:" + data.bufferInfo+",track:"+writeTrack);                    } catch (Exception e) {                        e.printStackTrace();                        LogTools.e("sent写入混合数据失败!" + e.getMessage());                    }finally {                        data.recycle();                    }                    break;                case MSG_STOP:                    LogTools.d("sent MuxerHandler MSG_STOP");                    if(mediaMuxer != null){                        try {                            mediaMuxer.stop();                        } catch (Exception e) {                            e.printStackTrace();                            LogTools.e("sent mediaMuxer.stop() 异常:" + e.getMessage());                        }                        try {                            mediaMuxer.release();                        } catch (Exception e) {                            e.printStackTrace();                            LogTools.e("sent mediaMuxer.release() 异常:" + e.toString());                        }                    }                    mediaMuxer = null;                    state = STATE.STOPPED;                    break;            }        }    }    @IntDef({TRACK_VIDEO, TRACK_AUDIO})    @Retention(RetentionPolicy.SOURCE)    public @interface TrackIndex {    }    public static class MuxerData{        int trackIndex;        ByteBuffer byteBuffer;        MediaCodec.BufferInfo bufferInfo;        private static final Pools.SynchronizedPool sPool = new Pools.SynchronizedPool(                10);        public static MuxerData obtain() {            MuxerData instance = sPool.acquire();            return (instance != null) ? instance : new MuxerData();        }        public static MuxerData obtain(int trackIndex, ByteBuffer byteBuffer, MediaCodec.BufferInfo bufferInfo) {            MuxerData instance = sPool.acquire();            if(instance == null)                instance = new MuxerData(trackIndex,byteBuffer,bufferInfo);            else                instance.set(trackIndex,byteBuffer,bufferInfo);            return instance;        }        public MuxerData(){        }        public void set(int trackIndex, ByteBuffer byteBuffer, MediaCodec.BufferInfo info){            this.trackIndex = trackIndex;            this.byteBuffer = byteBuffer;            //this.bufferInfo = bufferInfo;            if(this.bufferInfo == null){                this.bufferInfo = new MediaCodec.BufferInfo();            }            this.bufferInfo.set(info.offset, info.size, info.presentationTimeUs, info.flags);        }        public MuxerData(int trackIndex, ByteBuffer byteBuffer, MediaCodec.BufferInfo bufferInfo) {            set(trackIndex,byteBuffer,bufferInfo);        }        public void recycle() {            sPool.release(this);        }    }}

更多相关文章

  1. mybatisplus的坑 insert标签insert into select无参数问题的解决
  2. python起点网月票榜字体反爬案例
  3. Android(安卓)发送短信功能
  4. Android(安卓)Room 数据库
  5. Android之Fragment动态添加和移除Fragment
  6. android 数据保存与提取
  7. android数据库操作
  8. Android(安卓)中如何将带有html格式的文章转换成能在Android中显
  9. Android(安卓)setting中添加桌面循环滑动选项

随机推荐

  1. Dealing with the ! when you import and
  2. Android默认开机横屏
  3. Android-NDK编译:cocos2d-x(三) eclipse 导
  4. java之php、Android、JAVA、C# 3DES加密
  5. Android学习笔记(二)——Android的数据存储
  6. 私有析构函数 Android(安卓)代码分析
  7. Track change of IInterface::asBinder f
  8. 获取SearchView中的EditText,并改变其属性
  9. 裁判文书App(2020最新版) 逆向过程分析
  10. Androids——日常开发工具和组件集合