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();
}
}
}