Android中使用 MediaExtractor 和 MediaMuxer解析、封装 mp4 文件

最近开始学习Android下的封装和解封装技术,熟悉MediaExtractor和MediaMuxer的使用。

1、MainActivity.java文件:

packagecom.example.tongjiangsong.mediaextractmuxer;

importandroid.support.v7.app.AppCompatActivity;

importandroid.os.Bundle;

importandroid.view.View;

importandroid.widget.Button;

publicclassMainActivityextendsAppCompatActivity{

privateButton button;

@Override

protectedvoidonCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        button = (Button)findViewById(R.id.button);

button.setOnClickListener(newView.OnClickListener() {

@Override

publicvoidonClick(View v){

newExtractorMuxerThread().start();

            }

        });

    }

}

2、ExtractorMuxerThread.java文件:

packagecom.example.tongjiangsong.mediaextractmuxer;

importandroid.media.MediaCodec;

importandroid.media.MediaExtractor;

importandroid.media.MediaFormat;

importandroid.media.MediaMuxer;

importandroid.os.Environment;

importandroid.widget.Toast;

importjava.io.IOException;

importjava.nio.ByteBuffer;

importandroid.view.View;

publicclassExtractorMuxerThreadextendsThread{

@Override

publicvoidrun(){

super.run();

        mixer();

    }

publicvoidmixer(){

MediaExtractor videoExtractor =null;

MediaExtractor audioExtractor =null;

MediaMuxer mixMediaMuxer =null;

String outputVideoFilePath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/people.mp4";

String outputAudioFilePath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/qishi.aac";

String outputFilePath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/mixer.mp4";

try{

videoExtractor =newMediaExtractor();

            videoExtractor.setDataSource(outputVideoFilePath);

intvideoIndex = -1;

MediaFormat videoTrackFormat =null;

inttrackCount = videoExtractor.getTrackCount();

for(inti =0; i < trackCount; i++) {

                videoTrackFormat = videoExtractor.getTrackFormat(i);

if(videoTrackFormat.getString(MediaFormat.KEY_MIME).startsWith("video/")) {

                    videoIndex = i;

break;

                }

            }

audioExtractor =newMediaExtractor();

            audioExtractor.setDataSource(outputAudioFilePath);

intaudioIndex = -1;

MediaFormat audioTrackFormat =null;

            trackCount = audioExtractor.getTrackCount();

for(inti =0; i < trackCount; i++) {

                audioTrackFormat = audioExtractor.getTrackFormat(i);

if(audioTrackFormat.getString(MediaFormat.KEY_MIME).startsWith("audio/")) {

                    audioIndex = i;

break;

                }

            }

            videoExtractor.selectTrack(videoIndex);

            audioExtractor.selectTrack(audioIndex);

MediaCodec.BufferInfo videoBufferInfo =newMediaCodec.BufferInfo();

MediaCodec.BufferInfo audioBufferInfo =newMediaCodec.BufferInfo();

mixMediaMuxer =newMediaMuxer(outputFilePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);

intvideoTrackIndex = mixMediaMuxer.addTrack(videoTrackFormat);

intaudioTrackIndex = mixMediaMuxer.addTrack(audioTrackFormat);

            mixMediaMuxer.start();

ByteBuffer byteBuffer = ByteBuffer.allocate(1024*1024);

longvideotime;

longaudiotime;

            {

videoExtractor.readSampleData(byteBuffer,0);

if(videoExtractor.getSampleFlags() == MediaExtractor.SAMPLE_FLAG_SYNC) {

                    videoExtractor.advance();

                }

videoExtractor.readSampleData(byteBuffer,0);

longsampleTime = videoExtractor.getSampleTime();

                videoExtractor.advance();

videoExtractor.readSampleData(byteBuffer,0);

longsampleTime1 = 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);

longsampleTime = audioExtractor.getSampleTime();

                audioExtractor.advance();

audioExtractor.readSampleData(byteBuffer,0);

longsampleTime1 = audioExtractor.getSampleTime();

                audioExtractor.advance();

                audiotime = Math.abs(sampleTime - sampleTime1);

            }

            videoExtractor.unselectTrack(videoIndex);

            videoExtractor.selectTrack(videoIndex);

while(true) {

intdata = 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) {

intdata = 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();

            }

}catch(IOException e) {

            e.printStackTrace();

}finally{

if(mixMediaMuxer !=null) {

                mixMediaMuxer.stop();

                mixMediaMuxer.release();

            }

if(videoExtractor !=null){

                videoExtractor.release();

            }

if(audioExtractor !=null){

                audioExtractor.release();

            }

        }

    }

}

3、activity_main.xml文件:


xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context=".MainActivity">

   

android:id="@+id/button"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="解封装和封装!"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintLeft_toLeftOf="parent"

app:layout_constraintRight_toRightOf="parent"

app:layout_constraintTop_toTopOf="parent"/>

4、权限:

你可能感兴趣的:(Android中使用 MediaExtractor 和 MediaMuxer解析、封装 mp4 文件)