最近开始学习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">