android path拆分_Android多媒体之使用MediaExtractor与MediaMuxer分离音视频

MediaExtractor与MediaMuxer工具可以完美的将视频中的音视频分开来,可以对视频进行再配音合成达到自己的需求:

1.准备工作:声明基础变量

private final static String ROOT_PATH = Environment.getExternalStorageDirectory()

.getAbsolutePath()+"/Media";

private final static String MEDIA_DIVIDE_PATH = ROOT_PATH+"/divide";

private final static String MEDIA_DUBBING_PATH = ROOT_PATH+"/dubbing";

private String currentTaskPath = null;

public final static String AUDIO_MIME = "audio";

public final static String VIDEO_MIME = "video";

private String videoOutputPath;

public MediaDivider(){

initOutputPath();

}

private void initOutputPath(){

File file = new File(ROOT_PATH);

if (!file.exists()) {

file.mkdirs();

}

File divide = new File(MEDIA_DIVIDE_PATH);

if (!divide.exists()) {

divide.exists();

}

currentTaskPath = createCurrentTaskPath();

File currentTask = new File(currentTaskPath);

if (!currentTask.exists()) {

currentTask.mkdirs();

}

File dubbingPath = new File(MEDIA_DUBBING_PATH);

if (!dubbingPath.exists()) {

dubbingPath.mkdirs();

}

}

private String createCurrentTaskPath(){

return MEDIA_DIVIDE_PATH+"/"+System.currentTimeMillis();

}

2.开始分离音视频:

public void divideMedia(String sourceMediaPath,String divideMime){

MediaExtractor mediaExtractor = new MediaExtractor();

try {

mediaExtractor.setDataSource(sourceMediaPath);

int trackCount = mediaExtractor.getTrackCount();

for (int i=0;i

MediaFormat mediaFormat = mediaExtractor.getTrackFormat(i);

String mime = mediaFormat.getString(MediaFormat.KEY_MIME);

if (!mime.startsWith(divideMime)) {

continue;

}

int maxInputSize = mediaFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);

Log.d(TAG,"maxInputSize:"+maxInputSize);

ByteBuffer videoByteBuffer = ByteBuffer.allocate(maxInputSize);

if (divideMime.equals(AUDIO_MIME)) {

Log.d(TAG,"divide audio media to file");

String audioName = currentTaskPath+"/"

+sourceMediaPath.substring(sourceMediaPath.lastIndexOf('/')+1,sourceMediaPath.lastIndexOf('.'))

+"_audio_out.mp4";

Log.d(TAG,"audioName:"+audioName);

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

int audioTrack = mediaMuxer.addTrack(mediaFormat);

mediaMuxer.start();

divideToOutputAudio(mediaExtractor,mediaMuxer,videoByteBuffer,mediaFormat,audioTrack,i);

finish(mediaExtractor,mediaMuxer);

break;

} else if (divideMime.equals(VIDEO_MIME)) {

Log.d(TAG,"divide video media to file");

String videoName = currentTaskPath+"/"

+sourceMediaPath.substring(sourceMediaPath.lastIndexOf('/')+1,sourceMediaPath.lastIndexOf('.'))

+"_video_out.mp4";

Log.d(TAG,"videoName:"+videoName);

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

int videoTrack = mediaMuxer.addTrack(mediaFormat);

mediaMuxer.start();

divideToOutputVideo(mediaExtractor,mediaMuxer,videoByteBuffer,mediaFormat,videoTrack,i);

finish(mediaExtractor,mediaMuxer);

break;

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

该方法接受视频路径与所要分离出的媒体文件格式:audio或者video,根据媒体格式进行操作。

3.分离视频:

private void divideToOutputVideo(MediaExtractor mediaExtractor,MediaMuxer mediaMuxer,ByteBuffer byteBuffer,MediaFormat format,

int videoTrack,int videoTrackIndex) {

long videoDuration = format.getLong(MediaFormat.KEY_DURATION);

mediaExtractor.selectTrack(videoTrackIndex);

MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();

bufferInfo.presentationTimeUs = 0;

long videoFrameTimes;

mediaExtractor.readSampleData(byteBuffer,0);

if (mediaExtractor.getSampleFlags()!=MediaExtractor.SAMPLE_FLAG_SYNC) {

mediaExtractor.advance();

}

mediaExtractor.readSampleData(byteBuffer,0);

mediaExtractor.advance();

long firstFrame = mediaExtractor.getSampleTime();

mediaExtractor.advance();

mediaExtractor.readSampleData(byteBuffer,0);

long secondFrame = mediaExtractor.getSampleTime();

videoFrameTimes = Math.abs(secondFrame-firstFrame);

mediaExtractor.seekTo(0,MediaExtractor.SEEK_TO_CLOSEST_SYNC);

int sampleSize;

while ((sampleSize=mediaExtractor.readSampleData(byteBuffer,0))!=-1){

long presentTime = bufferInfo.presentationTimeUs;

if (presentTime>=videoDuration) {

mediaExtractor.unselectTrack(videoTrackIndex);

break;

}

mediaExtractor.advance();

bufferInfo.offset=0;

bufferInfo.flags=mediaExtractor.getSampleFlags();

bufferInfo.size=sampleSize;

mediaMuxer.writeSampleData(videoTrack,byteBuffer,bufferInfo);

bufferInfo.presentationTimeUs +=videoFrameTimes;

}

mediaExtractor.unselectTrack(videoTrackIndex);

}

4.分离出音频:

private void divideToOutputAudio(MediaExtractor mediaExtractor,MediaMuxer mediaMuxer,ByteBuffer byteBuffer,MediaFormat format,

int audioTrack,int audioTrackIndex){

int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);

int channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);

Log.d(TAG,"rate:"+sampleRate+",c:"+channelCount);

long audioDuration = format.getLong(MediaFormat.KEY_DURATION);

mediaExtractor.selectTrack(audioTrackIndex);//参数为多媒体文件MediaExtractor获取到的track count的索引,选择音频轨道

MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();

bufferInfo.presentationTimeUs = 0;

long audioSampleSize;

mediaExtractor.readSampleData(byteBuffer,0);

if (mediaExtractor.getSampleTime()==0) {

mediaExtractor.advance();

}

mediaExtractor.readSampleData(byteBuffer,0);

long firstRateSample = mediaExtractor.getSampleTime();

mediaExtractor.advance();

mediaExtractor.readSampleData(byteBuffer,0);

long secondRateSample = mediaExtractor.getSampleTime();

audioSampleSize = Math.abs(secondRateSample-firstRateSample);

mediaExtractor.seekTo(0,MediaExtractor.SEEK_TO_PREVIOUS_SYNC);

int sampleSize;

while ((sampleSize=mediaExtractor.readSampleData(byteBuffer,0))!=-1) {

int trackIndex = mediaExtractor.getSampleTrackIndex();

long presentationTimeUs = bufferInfo.presentationTimeUs;

Log.d(TAG,"trackIndex:"+trackIndex+",presentationTimeUs:"+presentationTimeUs);

if (presentationTimeUs>=audioDuration){

mediaExtractor.unselectTrack(audioTrackIndex);

break;

}

mediaExtractor.advance();

bufferInfo.offset=0;

bufferInfo.size=sampleSize;

mediaMuxer.writeSampleData(audioTrack,byteBuffer,bufferInfo);//audioTrack为通过mediaMuxer.add()获取到的

bufferInfo.presentationTimeUs += audioSampleSize;

}

mediaExtractor.unselectTrack(audioTrackIndex);

}

5.释放资源:

private void finish(MediaExtractor mediaExtractor,MediaMuxer mediaMuxer){

mediaMuxer.stop();

mediaMuxer.release();

mediaMuxer = null;

mediaExtractor.release();

mediaExtractor = null;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值