使用mediaMuxer实现音视频混合

 MediaMuxer使用步骤

1.创建对象 第一个参数是要输出的文件路径,第二个是输出格式

mediaMuxer = new MediaMuxer(outputVideoFilePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);

 2.添加视频轨或者音轨,根据添加顺序,生成index 在写入时会用到。

MediaFormat trackFormat = mediaExtractor.getTrackFormat(videoIndex);
mediaMuxer.addTrack(trackFormat);

3.开启混合

mediaMuxer.start();

 4.写入数据

bufferinfo的设置很关键 会影响文件大小
bufferInfo.size = data;
bufferInfo.offset = 0;
bufferInfo.flags = mediaExtractor.getSampleFlags();
bufferInfo.presentationTimeUs += videoSampleTime;

i就是前面添加的视频轨或者音轨的index
mediaMuxer.writeSampleData(i, byteBuffer, bufferInfo);

5.释放资源

mediaExtractor.release();
mediaMuxer.stop();
mediaMuxer.release();

 模块demo

public class Muxer {
    public MediaExtractor mediaExtractor;
    public String inputFilePath,outputVideoFilePath,outputFilePath,outputAudioFilePath;
    public MediaMuxer mediaMuxer;


    public Muxer(String inputFilePath,String outputVideoFilePath,String outputFilePath,String outputAudioFilePath){
        this.inputFilePath = inputFilePath;
        this.outputAudioFilePath = outputAudioFilePath;
        this.outputVideoFilePath = outputVideoFilePath;
        this.outputFilePath = outputFilePath;
    }
    @SuppressLint("WrongConstant")
    public void extractorVideo() {
        int videoIndex = -1;
        try {
            mediaExtractor = new MediaExtractor();
            mediaExtractor.setDataSource(inputFilePath); //数据源
            int trackCount = mediaExtractor.getTrackCount();
            for (int i = 0; i < trackCount; i++) {
                MediaFormat trackFormat = mediaExtractor.getTrackFormat(i);
                String string = trackFormat.getString(MediaFormat.KEY_MIME);
                if (string.startsWith("video/")) {
                    videoIndex = i;//得到具体轨道
                    break;
                }
            }
            mediaExtractor.selectTrack(videoIndex);
            MediaFormat trackFormat = mediaExtractor.getTrackFormat(videoIndex);
            mediaMuxer = new MediaMuxer(outputVideoFilePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
            int i = mediaMuxer.addTrack(trackFormat);

            ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 1024);
            MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
            mediaMuxer.start();

            long videoSampleTime;
            //获取每一帧的时间
            {
                mediaExtractor.readSampleData(byteBuffer, 0);
                if (mediaExtractor.getSampleFlags() == MediaExtractor.SAMPLE_FLAG_SYNC) {
                    mediaExtractor.advance();
                }
                mediaExtractor.readSampleData(byteBuffer, 0);
                long sampleTime = mediaExtractor.getSampleTime();
                mediaExtractor.advance();

                mediaExtractor.readSampleData(byteBuffer, 0);
                long sampleTime1 = mediaExtractor.getSampleTime();
                videoSampleTime = Math.abs(sampleTime - sampleTime1);
            }
            //重新选择 否则会丢掉上面的三帧
            mediaExtractor.unselectTrack(videoIndex);
            mediaExtractor.selectTrack(videoIndex);

            while (true) {
                int data = mediaExtractor.readSampleData(byteBuffer, 0);
                if (data < 0) {
                    break;
                }

                bufferInfo.size = data;
                bufferInfo.offset = 0;
                bufferInfo.flags = mediaExtractor.getSampleFlags();
                bufferInfo.presentationTimeUs += videoSampleTime;

                mediaMuxer.writeSampleData(i, byteBuffer, bufferInfo);

                mediaExtractor.advance();
            }
            //Toast.makeText(this, "ok", Toast.LENGTH_SHORT).show();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            mediaExtractor.release();
            mediaMuxer.stop();
            mediaMuxer.release();
        }
    }

    @SuppressLint("WrongConstant")
    public void extractorAudio() {
        mediaExtractor = new MediaExtractor();
        int audioIndex = -1;
        try {
            mediaExtractor.setDataSource(inputFilePath);
            int trackCount = mediaExtractor.getTrackCount();
            for (int i = 0; i < trackCount; i++) {
                MediaFormat trackFormat = mediaExtractor.getTrackFormat(i);
                String string = trackFormat.getString(MediaFormat.KEY_MIME);
                if (string.startsWith("audio/")) {
                    audioIndex = i;
                }
            }
            mediaExtractor.selectTrack(audioIndex);
            MediaFormat trackFormat = mediaExtractor.getTrackFormat(audioIndex);
            mediaMuxer = new MediaMuxer(outputAudioFilePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);

            int i = mediaMuxer.addTrack(trackFormat);
            mediaMuxer.start();

            ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 1024);
            MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();

            long time;
            {
                mediaExtractor.readSampleData(byteBuffer, 0);
                if (mediaExtractor.getSampleFlags() == MediaExtractor.SAMPLE_FLAG_SYNC) {
                    mediaExtractor.advance();
                }
                mediaExtractor.readSampleData(byteBuffer, 0);
                long sampleTime = mediaExtractor.getSampleTime();
                mediaExtractor.advance();

                mediaExtractor.readSampleData(byteBuffer, 0);
                long sampleTime1 = mediaExtractor.getSampleTime();
                mediaExtractor.advance();

                time = Math.abs(sampleTime - sampleTime1);
            }

            mediaExtractor.unselectTrack(audioIndex);
            mediaExtractor.selectTrack(audioIndex);
            while (true) {
                int data = mediaExtractor.readSampleData(byteBuffer, 0);
                if (data < 0) {
                    break;
                }

                bufferInfo.size = data;
                bufferInfo.flags = mediaExtractor.getSampleFlags();
                bufferInfo.offset = 0;
                bufferInfo.presentationTimeUs += time;

                mediaMuxer.writeSampleData(i, byteBuffer, bufferInfo);
                mediaExtractor.advance();
            }


            //Toast.makeText(this, "ok", Toast.LENGTH_SHORT).show();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            mediaExtractor.release();
            mediaMuxer.stop();
            mediaMuxer.release();
        }
    }

    @SuppressLint("WrongConstant")
    public void mix() {
        MediaExtractor videoExtractor = null;
        MediaExtractor audioExtractor = null;
        MediaMuxer mixMediaMuxer = null;
        try {
            videoExtractor = new MediaExtractor();
            videoExtractor.setDataSource(outputVideoFilePath);
            int videoIndex = -1;
            MediaFormat videoTrackFormat = null;
            int trackCount = videoExtractor.getTrackCount();
            for (int i = 0; i < trackCount; i++) {
                videoTrackFormat = videoExtractor.getTrackFormat(i);
                if (videoTrackFormat.getString(MediaFormat.KEY_MIME).startsWith("video/")) {
                    videoIndex = i;
                }
            }

            audioExtractor = new MediaExtractor();
            audioExtractor.setDataSource(outputAudioFilePath);
            int audioIndex = -1;
            MediaFormat audioTrackFormat = null;
            trackCount = audioExtractor.getTrackCount();
            for (int i = 0; i < trackCount; i++) {
                audioTrackFormat = audioExtractor.getTrackFormat(i);
                if (audioTrackFormat.getString(MediaFormat.KEY_MIME).startsWith("audio/")) {
                    audioIndex = i;
                }
            }

            videoExtractor.selectTrack(videoIndex);
            audioExtractor.selectTrack(audioIndex);

            MediaCodec.BufferInfo videoBufferInfo = new MediaCodec.BufferInfo();
            MediaCodec.BufferInfo audioBufferInfo = new MediaCodec.BufferInfo();

            mixMediaMuxer = new MediaMuxer(outputFilePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
            int videoTrackIndex = mixMediaMuxer.addTrack(videoTrackFormat);
            int audioTrackIndex = mixMediaMuxer.addTrack(audioTrackFormat);

            mixMediaMuxer.start();

            ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 1024);
            long videotime;
            long audiotime;

            {
                videoExtractor.readSampleData(byteBuffer, 0);
                if (videoExtractor.getSampleFlags() == MediaExtractor.SAMPLE_FLAG_SYNC) {
                    videoExtractor.advance();
                }
                videoExtractor.readSampleData(byteBuffer, 0);
                long sampleTime = videoExtractor.getSampleTime();
                videoExtractor.advance();
                videoExtractor.readSampleData(byteBuffer, 0);
                long sampleTime1 = videoExtractor.getSampleTime();
                videoExtractor.advance();

                videotime = Math.abs(sampleTime - sampleTime1);
            }

            {
                audioExtractor.readSampleData(byteBuffer, 0);
                if (audioExtractor.getSampleFlags() == MediaExtractor.SAMPLE_FLAG_SYNC) {
                    audioExtractor.advance();
                }
                audioExtractor.readSampleData(byteBuffer, 0);
                long sampleTime = audioExtractor.getSampleTime();
                audioExtractor.advance();
                audioExtractor.readSampleData(byteBuffer, 0);
                long sampleTime1 = audioExtractor.getSampleTime();
                audioExtractor.advance();

                audiotime = Math.abs(sampleTime - sampleTime1);
            }

            videoExtractor.unselectTrack(videoIndex);
            videoExtractor.selectTrack(videoIndex);

            while (true) {
                int data = videoExtractor.readSampleData(byteBuffer, 0);
                if (data < 0) {
                    break;
                }
                videoBufferInfo.size = data;
                videoBufferInfo.presentationTimeUs += videotime;
                videoBufferInfo.offset = 0;
                videoBufferInfo.flags = videoExtractor.getSampleFlags();

                mixMediaMuxer.writeSampleData(videoTrackIndex, byteBuffer, videoBufferInfo);
                videoExtractor.advance();
            }

            while (true) {
                int data = audioExtractor.readSampleData(byteBuffer, 0);
                if (data < 0) {
                    break;
                }
                audioBufferInfo.size = data;
                audioBufferInfo.presentationTimeUs += audiotime;
                audioBufferInfo.offset = 0;
                audioBufferInfo.flags = audioExtractor.getSampleFlags();

                mixMediaMuxer.writeSampleData(audioTrackIndex, byteBuffer, audioBufferInfo);
                audioExtractor.advance();
            }
            //Toast.makeText(this, "ok", Toast.LENGTH_SHORT).show();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (mixMediaMuxer != null) {
                mixMediaMuxer.stop();
                mixMediaMuxer.release();
            }
            videoExtractor.release();
            audioExtractor.release();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/xiaowang_lj/article/details/128355557