使用MediaMuxer裁剪视频

MediaPlayer的使用

  • 使用MediaMuxer裁剪视频
    • 1.解封装,获取不同tracks上的format
    • 2.配置MediaMuxer
    • 3.向MediaMuxer中写入数据
    • 4.释放资源

使用MediaMuxer裁剪视频

剪辑的过程大概是,先把封装格式的视频文件通过MediaExtractor进行解封装操作,分出不同的tracks,然后针对不同的tracks进行seekTo到我们需要开始裁剪的地方,然后通过MediaMuxer进行合并成封装格式
使用MediaMuxer裁剪视频_第1张图片
简要步骤如下

1.解封装,获取不同tracks上的format

mediaExtractor.setDataSource(srcPath);
for(int i=0;i<mediaExtractor.getTrackCount();i++){
    if(mediaExtractor.getTrackFormat(i).getString(MediaFormat.KEY_MIME).startsWith("video/")){
        sourceVideoTrack = i;
    }else if(mediaExtractor.getTrackFormat(i).getString(MediaFormat.KEY_MIME).startsWith("audio/")){
        sourceAudioTrack = i;
    }
}
videoFormat = mediaExtractor.getTrackFormat(sourceVideoTrack);
audioFormat = mediaExtractor.getTrackFormat(sourceAudioTrack);

2.配置MediaMuxer

(1)初始化该MediaMuxer

//dstPath_cut 为保存的目的地址
mediaMuxer = new MediaMuxer(dstPath_cut, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);

(2)addTrack到MediaMuxer

//视频部分
//把视频部分对应的format取出,并将其addTrack到mediaMuxer中
videoTrackIndex = mediaMuxer.addTrack(videoFormat);   //addTrack后返回的Index是要保存的,要在后面writeSampleData中使用	

//注意视频本身的rotation
int rotation = videoFormat.getInteger(MediaFormat.KEY_ROTATION);
mediaMuxer.setOrientationHint(rotation);

-----------------------------------------------------------------
//音频部分
audioTrackIndex = mediaMuxer.addTrack(audioFormat);

(3)启动MediaMuxer

mediaMuxer.start();

3.向MediaMuxer中写入数据

准备一个ByteBuffer来接收暂存数据

ByteBuffer inputBuffer = ByteBuffer.allocate(BufferSize); //这个BufferSize的大小没有明确的限定,适合即可
    //可以通过mediaFormat.getInteger("KEY_MAX_INPUT_SIZE")来获取

写数据
(1)视频部分

  //视频部分
    mediaExtractor.selectTrack(sourceVideoTrack);
    MediaCodec.BufferInfo videoInfo = new MediaCodec.BufferInfo();
    //beginTime指的是裁剪的开始时间,单位秒
    mediaExtractor.seekTo(beginTime * 1000000, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
    
    while(true){
            int sampleSize = mediaExtractor.readSampleData(inputBuffer,0);
            if(sampleSize<0){
                mediaExtractor.unselectTrack(sourceVideoTrack);
                break;
            }
            int trackIndex = mediaExtractor.getSampleTrackIndex();
            //获取时间戳
            long presentationTimeUs = mediaExtractor.getSampleTime();
            //获取帧类型,只能识别是否为I帧
            int sampleFlag = mediaExtractor.getSampleFlags();
            
                //一定要填满 bufferInfo的参数
                videoInfo.offset = 0;
                videoInfo.size = sampleSize;
                videoInfo.flags = sampleFlag;
                videoInfo.presentationTimeUs=Math.round((presentationTimeUs) * isChangeSpeed);
            //真正在这里写数据,videoTrackIndex就是addTrack返回的值
            //inputBuffer是从extractor中read出来的数据
            //videoinfo就是关于这个buffer的信息
            mediaMuxer.writeSampleData(videoTrackIndex, inputBuffer, videoInfo);
            mediaExtractor.advance();


        }

(2)音频部分

mediaExtractor.selectTrack(sourceAudioTrack);
MediaCodec.BufferInfo audioInfo = new MediaCodec.BufferInfo();
mediaExtractor.seekTo(beginTime * 1000000, MediaExtractor.SEEK_TO_CLOSEST_SYNC);

while(true){
            int sampleSize = mediaExtractor.readSampleData(inputBuffer,0);
            if(sampleSize<0){
                mediaExtractor.unselectTrack(sourceAudioTrack);
                break;
            }
            int trackIndex = mediaExtractor.getSampleTrackIndex();
            //获取时间戳
            long presentationTimeUs = mediaExtractor.getSampleTime();
            //获取帧类型,只能识别是否为I帧
            int sampleFlag = mediaExtractor.getSampleFlags();
            

            audioInfo.offset = 0;
            audioInfo.size = sampleSize;
            audioInfo.flags = sampleFlag;
            audioInfo.presentationTimeUs=presentationTimeUs;
            
            mediaMuxer.writeSampleData(audioTrackIndex, inputBuffer, audioInfo);
            mediaExtractor.advance();


        }

4.释放资源

		mediaMuxer.stop();
        mediaMuxer.release();
        mediaExtractor.release();
        mediaExtractor = null;

你可能感兴趣的:(使用MediaMuxer裁剪视频)