Android提供了一个MediaExtractor类,可以用来分离容器中的视频track和音频track,下面的例子展示了使用MediaExtractor和MediaMuxer来实现视频的换音:

private void muxingAudioAndVideo() throws IOException {    MediaMuxer mMediaMuxer = new MediaMuxer(mOutputVideoPath,                 MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);    // 视频的MediaExtractor    MediaExtractor mVideoExtractor = new MediaExtractor();    mVideoExtractor.setDataSource(mVideoPath);    int videoTrackIndex = -1;    for (int i = 0; i < mVideoExtractor.getTrackCount(); i++) {        MediaFormat format = mVideoExtractor.getTrackFormat(i);        if (format.getString(MediaFormat.KEY_MIME).startsWith("video/")) {            mVideoExtractor.selectTrack(i);            videoTrackIndex = mMediaMuxer.addTrack(format);            break;        }    }    // 音频的MediaExtractor    MediaExtractor mAudioExtractor = new MediaExtractor();    mAudioExtractor.setDataSource(mAudioPath);    int audioTrackIndex = -1;    for (int i = 0; i < mAudioExtractor.getTrackCount(); i++) {        MediaFormat format = mAudioExtractor.getTrackFormat(i);        if (format.getString(MediaFormat.KEY_MIME).startsWith("audio/")) {            mAudioExtractor.selectTrack(i);            audioTrackIndex = mMediaMuxer.addTrack(format);        }    }    // 添加完所有轨道后start    mMediaMuxer.start();    // 封装视频track    if (-1 != videoTrackIndex) {        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();        info.presentationTimeUs = 0;        ByteBuffer buffer = ByteBuffer.allocate(100 * 1024);        while (true) {            int sampleSize = mVideoExtractor.readSampleData(buffer, 0);            if (sampleSize < 0) {                break;            }            info.offset = 0;            info.size = sampleSize;            info.flags = MediaCodec.BUFFER_FLAG_SYNC_FRAME;            info.presentationTimeUs = mVideoExtractor.getSampleTime();            mMediaMuxer.writeSampleData(videoTrackIndex, buffer, info);            mVideoExtractor.advance();        }    }    // 封装音频track    if (-1 != audioTrackIndex) {        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();        info.presentationTimeUs = 0;        ByteBuffer buffer = ByteBuffer.allocate(100 * 1024);        while (true) {            int sampleSize = mAudioExtractor.readSampleData(buffer, 0);            if (sampleSize < 0) {                break;            }            info.offset = 0;            info.size = sampleSize;            info.flags = MediaCodec.BUFFER_FLAG_SYNC_FRAME;            info.presentationTimeUs = mAudioExtractor.getSampleTime();            mMediaMuxer.writeSampleData(audioTrackIndex, buffer, info);            mAudioExtractor.advance();        }    }    // 释放MediaExtractor    mVideoExtractor.release();    mAudioExtractor.release();    // 释放MediaMuxer    mMediaMuxer.stop();    mMediaMuxer.release();}

MediaExtractor的接口比较简单,首先通过setDataSource()设置数据源,数据源可以是本地文件地址,也可以是网络地址:

MediaExtractor mVideoExtractor = new MediaExtractor();mVideoExtractor.setDataSource(mVideoPath);

然后可以通过getTrackFormat(int index)来获取各个track的MediaFormat,通过MediaFormat来获取track的详细信息,如:MimeType、分辨率、采样频率、帧率等等:

for (int i = 0; i < mVideoExtractor.getTrackCount(); i++) {    MediaFormat format = mVideoExtractor.getTrackFormat(i);}

获取到track的详细信息后,通过selectTrack(int index)选择指定的通道:

if (format.getString(MediaFormat.KEY_MIME).startsWith("video/")) {    mVideoExtractor.selectTrack(i);    break;}

指定通道之后就可以从MediaExtractor中读取数据了:

while (true) {    int sampleSize = mVideoExtractor.readSampleData(buffer, 0);    if (sampleSize < 0) {        break;    }    // do something    mVideoExtractor.advance();  // 移动到下一帧}

在读取结束之后,记得释放资源:

mVideoExtractor.release();

更多相关文章

  1. 腾讯微博客户端开发视频--若水(第三集、第四集)
  2. Android(安卓)VideoView播放视频
  3. 音视频转码合成
  4. Android调用系统摄像头--使用MediaRecorder--2--使用MediaRecord
  5. android 随手记 videoview循环播放网络视频 和mediaplayer+sufac
  6. Android(安卓)选择图片、上传图片之PictureSelector
  7. Android视频方向为什么出现问题以及Android视频应用开发中的处理
  8. android和PC(Python)通过USB(adb模式)基于Socket传输图像(视频)
  9. Android(java方法)上实现mp4的分割和拼接 (二)

随机推荐

  1. android init进程解析init.rc过程
  2. Android(安卓)requires compiler complia
  3. Android动画开发——Animation动画效果
  4. android topic:Resource Types
  5. Android之View和ViewGroup事件分发
  6. Android中Retrofit的简要介绍
  7. 布局动画 属性初始 android:animateLayou
  8. android layout_weight讲解
  9. 针对4.0版本及以上版本的sharedpreferenc
  10. Android(安卓)根据 Url 跳转应用