直接上代码
/**
* 分离MP4文件的音频或视频轨道,并打印PTS
* @param isAudio:true:分离音频轨道 false:分离视频轨道
* @param inputPath:要分离的目标文件路径
* @param outputPath: 分离后的文件保存路径*/
@SuppressLint("WrongConstant")
public static void extractAudio(boolean isAudio, String inputPath, String outputPath) {
MediaExtractor extractor = null;
MediaMuxer muxer = null;
try {
// 创建MediaExtractor来读取MP4文件
extractor = new MediaExtractor();
extractor.setDataSource(inputPath);
// 查找轨道
int trackIndex = -1;
for (int i = 0; i < extractor.getTrackCount(); i++) {
MediaFormat format = extractor.getTrackFormat(i);
String mime = format.getString(MediaFormat.KEY_MIME);
if (mime.startsWith(isAudio ? "audio/" : "video/")) {//根据参数找到音频或视频轨道的下标
trackIndex = i;
break;
}
}
if (trackIndex < 0) {
throw new RuntimeException("No audio track found in " + inputPath);
}
// 选择轨道
extractor.selectTrack(trackIndex);
// 创建MediaMuxer来写入文件
muxer = new MediaMuxer(outputPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
MediaFormat trackFormat = extractor.getTrackFormat(trackIndex);
int muxerTrackIndex = muxer.addTrack(trackFormat);
muxer.start();
// 分离音/视频流并写入文件
ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
boolean sawInputEOS = false;
boolean sawOutputEOS = false;
while (!sawOutputEOS) {
int trackIndex2 = extractor.getSampleTrackIndex();
int sampleSize = extractor.readSampleData(buffer, 0);
if (sampleSize < 0) {
sawInputEOS = true;
sampleSize = 0;
}
if (sampleSize > 0) {
bufferInfo.size = sampleSize;
bufferInfo.presentationTimeUs = extractor.getSampleTime();
Log.i(TAG, "PTS=" + bufferInfo.presentationTimeUs);//时间戳
bufferInfo.flags = extractor.getSampleFlags();
muxer.writeSampleData(muxerTrackIndex, buffer, bufferInfo);
extractor.advance();
}
if (sawInputEOS) {
muxer.stop();
muxer.release();
sawOutputEOS = true;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (extractor != null) {
extractor.release();
}
if (muxer != null) {
muxer.release();
}
}
}